@@ -0,0 +1,29 @@ |
||
1 |
+# EditorConfig is awesome: http://EditorConfig.org |
|
2 |
+ |
|
3 |
+# top-most EditorConfig file |
|
4 |
+root = true |
|
5 |
+ |
|
6 |
+# Unix-style newlines with a newline ending every file |
|
7 |
+[*] |
|
8 |
+end_of_line = lf |
|
9 |
+insert_final_newline = false |
|
10 |
+ |
|
11 |
+# 4 space indentation |
|
12 |
+[*.py] |
|
13 |
+indent_style = space |
|
14 |
+indent_size = 4 |
|
15 |
+ |
|
16 |
+# Tab indentation (no size specified) |
|
17 |
+[*.js] |
|
18 |
+indent_style = space |
|
19 |
+indent_size = 4 |
|
20 |
+ |
|
21 |
+# Tab indentation (no size specified) |
|
22 |
+[*.html] |
|
23 |
+indent_style = space |
|
24 |
+indent_size = 4 |
|
25 |
+ |
|
26 |
+# Matches the exact files either package.json or .travis.yml |
|
27 |
+[{package.json,.travis.yml}] |
|
28 |
+indent_style = space |
|
29 |
+indent_size = 2 |
@@ -0,0 +1,14 @@ |
||
1 |
+<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
+<project version="4"> |
|
3 |
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false"> |
|
4 |
+ <OptionsSetting value="true" id="Add" /> |
|
5 |
+ <OptionsSetting value="true" id="Remove" /> |
|
6 |
+ <OptionsSetting value="true" id="Checkout" /> |
|
7 |
+ <OptionsSetting value="true" id="Update" /> |
|
8 |
+ <OptionsSetting value="true" id="Status" /> |
|
9 |
+ <OptionsSetting value="true" id="Edit" /> |
|
10 |
+ <ConfirmationsSetting value="0" id="Add" /> |
|
11 |
+ <ConfirmationsSetting value="0" id="Remove" /> |
|
12 |
+ </component> |
|
13 |
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7.12+ (/usr/bin/python2.7)" project-jdk-type="Python SDK" /> |
|
14 |
+</project> |
@@ -0,0 +1,8 @@ |
||
1 |
+<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
+<project version="4"> |
|
3 |
+ <component name="ProjectModuleManager"> |
|
4 |
+ <modules> |
|
5 |
+ <module fileurl="file://$PROJECT_DIR$/.idea/tamron.iml" filepath="$PROJECT_DIR$/.idea/tamron.iml" /> |
|
6 |
+ </modules> |
|
7 |
+ </component> |
|
8 |
+</project> |
@@ -0,0 +1,26 @@ |
||
1 |
+<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
+<module type="PYTHON_MODULE" version="4"> |
|
3 |
+ <component name="FacetManager"> |
|
4 |
+ <facet type="django" name="Django"> |
|
5 |
+ <configuration> |
|
6 |
+ <option name="rootFolder" value="$MODULE_DIR$" /> |
|
7 |
+ <option name="settingsModule" value="tamron/settings.py" /> |
|
8 |
+ <option name="manageScript" value="manage.py" /> |
|
9 |
+ <option name="environment" value="<map/>" /> |
|
10 |
+ <option name="commandsToSkip" value="" /> |
|
11 |
+ </configuration> |
|
12 |
+ </facet> |
|
13 |
+ </component> |
|
14 |
+ <component name="NewModuleRootManager"> |
|
15 |
+ <content url="file://$MODULE_DIR$" /> |
|
16 |
+ <orderEntry type="inheritedJdk" /> |
|
17 |
+ <orderEntry type="sourceFolder" forTests="false" /> |
|
18 |
+ </component> |
|
19 |
+ <component name="TemplatesService"> |
|
20 |
+ <option name="TEMPLATE_CONFIGURATION" value="Django" /> |
|
21 |
+ </component> |
|
22 |
+ <component name="TestRunnerService"> |
|
23 |
+ <option name="projectConfiguration" value="py.test" /> |
|
24 |
+ <option name="PROJECT_TEST_RUNNER" value="py.test" /> |
|
25 |
+ </component> |
|
26 |
+</module> |
@@ -0,0 +1,634 @@ |
||
1 |
+<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
+<project version="4"> |
|
3 |
+ <component name="ChangeListManager"> |
|
4 |
+ <list default="true" id="8287082c-5144-4790-9da1-578e292318f7" name="Default" comment="" /> |
|
5 |
+ <ignored path="tamron.iws" /> |
|
6 |
+ <ignored path=".idea/workspace.xml" /> |
|
7 |
+ <ignored path=".idea/dataSources.local.xml" /> |
|
8 |
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> |
|
9 |
+ <option name="TRACKING_ENABLED" value="true" /> |
|
10 |
+ <option name="SHOW_DIALOG" value="false" /> |
|
11 |
+ <option name="HIGHLIGHT_CONFLICTS" value="true" /> |
|
12 |
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> |
|
13 |
+ <option name="LAST_RESOLUTION" value="IGNORE" /> |
|
14 |
+ </component> |
|
15 |
+ <component name="CreatePatchCommitExecutor"> |
|
16 |
+ <option name="PATCH_PATH" value="" /> |
|
17 |
+ </component> |
|
18 |
+ <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" /> |
|
19 |
+ <component name="FavoritesManager"> |
|
20 |
+ <favorites_list name="tamron" /> |
|
21 |
+ </component> |
|
22 |
+ <component name="FileEditorManager"> |
|
23 |
+ <leaf> |
|
24 |
+ <file leaf-file-name="tamron.ini" pinned="false" current-in-tab="false"> |
|
25 |
+ <entry file="file://$PROJECT_DIR$/tamron/uwsgi.bak/tamron.ini"> |
|
26 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
27 |
+ <state relative-caret-position="255"> |
|
28 |
+ <caret line="17" column="61" selection-start-line="17" selection-start-column="61" selection-end-line="17" selection-end-column="61" /> |
|
29 |
+ <folding /> |
|
30 |
+ </state> |
|
31 |
+ </provider> |
|
32 |
+ </entry> |
|
33 |
+ </file> |
|
34 |
+ <file leaf-file-name="tamron_nginx.conf" pinned="false" current-in-tab="true"> |
|
35 |
+ <entry file="file://$PROJECT_DIR$/tamron/uwsgi.bak/tamron_nginx.conf"> |
|
36 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
37 |
+ <state relative-caret-position="480"> |
|
38 |
+ <caret line="32" column="50" selection-start-line="32" selection-start-column="50" selection-end-line="32" selection-end-column="50" /> |
|
39 |
+ <folding /> |
|
40 |
+ </state> |
|
41 |
+ </provider> |
|
42 |
+ </entry> |
|
43 |
+ </file> |
|
44 |
+ </leaf> |
|
45 |
+ </component> |
|
46 |
+ <component name="FileTemplateManagerImpl"> |
|
47 |
+ <option name="RECENT_TEMPLATES"> |
|
48 |
+ <list> |
|
49 |
+ <option value="Python Script" /> |
|
50 |
+ </list> |
|
51 |
+ </option> |
|
52 |
+ </component> |
|
53 |
+ <component name="IdeDocumentHistory"> |
|
54 |
+ <option name="CHANGED_PATHS"> |
|
55 |
+ <list> |
|
56 |
+ <option value="$PROJECT_DIR$/tamron/basemodels.py" /> |
|
57 |
+ <option value="$PROJECT_DIR$/account/admin.py" /> |
|
58 |
+ <option value="$PROJECT_DIR$/product/admin.py" /> |
|
59 |
+ <option value="$PROJECT_DIR$/integral/admin.py" /> |
|
60 |
+ <option value="$PROJECT_DIR$/page/views.py" /> |
|
61 |
+ <option value="$PROJECT_DIR$/product/models.py" /> |
|
62 |
+ <option value="$PROJECT_DIR$/integral/models.py" /> |
|
63 |
+ <option value="$PROJECT_DIR$/tamron/settings.py" /> |
|
64 |
+ <option value="$PROJECT_DIR$/api/urls.py" /> |
|
65 |
+ <option value="$PROJECT_DIR$/tamron/local_settings.py" /> |
|
66 |
+ <option value="$PROJECT_DIR$/page/templates/page/clerk_oauth.html" /> |
|
67 |
+ <option value="$PROJECT_DIR$/page/sale_views.py" /> |
|
68 |
+ <option value="$PROJECT_DIR$/page/templates/page/clerk_sale.html" /> |
|
69 |
+ <option value="$PROJECT_DIR$/page/templates/page/clerk_into.html" /> |
|
70 |
+ <option value="$PROJECT_DIR$/tamron/urls.py" /> |
|
71 |
+ <option value="$PROJECT_DIR$/page/info_views.py" /> |
|
72 |
+ <option value="$PROJECT_DIR$/utils/error/errno_utils.py" /> |
|
73 |
+ <option value="$PROJECT_DIR$/page/oauth_views.py" /> |
|
74 |
+ <option value="$PROJECT_DIR$/account/models.py" /> |
|
75 |
+ <option value="$PROJECT_DIR$/page/templates/page/clerk_info.html" /> |
|
76 |
+ <option value="$PROJECT_DIR$/tamron/uwsgi.bak/tamron.ini" /> |
|
77 |
+ <option value="$PROJECT_DIR$/tamron/uwsgi.bak/tamron_nginx.conf" /> |
|
78 |
+ </list> |
|
79 |
+ </option> |
|
80 |
+ </component> |
|
81 |
+ <component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" /> |
|
82 |
+ <component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" /> |
|
83 |
+ <component name="JsGulpfileManager"> |
|
84 |
+ <detection-done>true</detection-done> |
|
85 |
+ <sorting>DEFINITION_ORDER</sorting> |
|
86 |
+ </component> |
|
87 |
+ <component name="ProjectFrameBounds"> |
|
88 |
+ <option name="x" value="65" /> |
|
89 |
+ <option name="y" value="24" /> |
|
90 |
+ <option name="width" value="1301" /> |
|
91 |
+ <option name="height" value="744" /> |
|
92 |
+ </component> |
|
93 |
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false"> |
|
94 |
+ <OptionsSetting value="true" id="Add" /> |
|
95 |
+ <OptionsSetting value="true" id="Remove" /> |
|
96 |
+ <OptionsSetting value="true" id="Checkout" /> |
|
97 |
+ <OptionsSetting value="true" id="Update" /> |
|
98 |
+ <OptionsSetting value="true" id="Status" /> |
|
99 |
+ <OptionsSetting value="true" id="Edit" /> |
|
100 |
+ <ConfirmationsSetting value="0" id="Add" /> |
|
101 |
+ <ConfirmationsSetting value="0" id="Remove" /> |
|
102 |
+ </component> |
|
103 |
+ <component name="ProjectView"> |
|
104 |
+ <navigator currentView="ProjectPane" proportions="" version="1"> |
|
105 |
+ <flattenPackages /> |
|
106 |
+ <showMembers /> |
|
107 |
+ <showModules /> |
|
108 |
+ <showLibraryContents /> |
|
109 |
+ <hideEmptyPackages /> |
|
110 |
+ <abbreviatePackageNames /> |
|
111 |
+ <autoscrollToSource /> |
|
112 |
+ <autoscrollFromSource /> |
|
113 |
+ <sortByType /> |
|
114 |
+ <manualOrder /> |
|
115 |
+ <foldersAlwaysOnTop value="true" /> |
|
116 |
+ </navigator> |
|
117 |
+ <panes> |
|
118 |
+ <pane id="Scratches" /> |
|
119 |
+ <pane id="Scope" /> |
|
120 |
+ <pane id="ProjectPane"> |
|
121 |
+ <subPane> |
|
122 |
+ <PATH> |
|
123 |
+ <PATH_ELEMENT> |
|
124 |
+ <option name="myItemId" value="tamron" /> |
|
125 |
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> |
|
126 |
+ </PATH_ELEMENT> |
|
127 |
+ </PATH> |
|
128 |
+ <PATH> |
|
129 |
+ <PATH_ELEMENT> |
|
130 |
+ <option name="myItemId" value="tamron" /> |
|
131 |
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> |
|
132 |
+ </PATH_ELEMENT> |
|
133 |
+ <PATH_ELEMENT> |
|
134 |
+ <option name="myItemId" value="tamron" /> |
|
135 |
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> |
|
136 |
+ </PATH_ELEMENT> |
|
137 |
+ </PATH> |
|
138 |
+ </subPane> |
|
139 |
+ </pane> |
|
140 |
+ </panes> |
|
141 |
+ </component> |
|
142 |
+ <component name="PropertiesComponent"> |
|
143 |
+ <property name="last_opened_file_path" value="$PROJECT_DIR$" /> |
|
144 |
+ <property name="WebServerToolWindowFactoryState" value="false" /> |
|
145 |
+ <property name="js-jscs-nodeInterpreter" value="$USER_HOME$/.nvm/versions/node/v6.10.0/bin/node" /> |
|
146 |
+ </component> |
|
147 |
+ <component name="RecentsManager"> |
|
148 |
+ <key name="CopyFile.RECENT_KEYS"> |
|
149 |
+ <recent name="$PROJECT_DIR$/page" /> |
|
150 |
+ <recent name="$PROJECT_DIR$/page/templates/page" /> |
|
151 |
+ </key> |
|
152 |
+ </component> |
|
153 |
+ <component name="RunManager" selected="Django server.tamron"> |
|
154 |
+ <configuration default="true" type="DjangoTestsConfigurationType" factoryName="Django tests"> |
|
155 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
156 |
+ <option name="PARENT_ENVS" value="true" /> |
|
157 |
+ <envs> |
|
158 |
+ <env name="PYTHONUNBUFFERED" value="1" /> |
|
159 |
+ </envs> |
|
160 |
+ <option name="SDK_HOME" value="" /> |
|
161 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
162 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
163 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
164 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
165 |
+ <module name="tamron" /> |
|
166 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
167 |
+ <option name="TARGET" value="" /> |
|
168 |
+ <option name="SETTINGS_FILE" value="" /> |
|
169 |
+ <option name="CUSTOM_SETTINGS" value="false" /> |
|
170 |
+ <option name="USE_OPTIONS" value="false" /> |
|
171 |
+ <option name="OPTIONS" value="" /> |
|
172 |
+ <method /> |
|
173 |
+ </configuration> |
|
174 |
+ <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug"> |
|
175 |
+ <method /> |
|
176 |
+ </configuration> |
|
177 |
+ <configuration default="true" type="PyBehaveRunConfigurationType" factoryName="Behave"> |
|
178 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
179 |
+ <option name="PARENT_ENVS" value="true" /> |
|
180 |
+ <envs /> |
|
181 |
+ <option name="SDK_HOME" value="" /> |
|
182 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
183 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
184 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
185 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
186 |
+ <module name="tamron" /> |
|
187 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
188 |
+ <option name="ADDITIONAL_ARGS" value="" /> |
|
189 |
+ <method /> |
|
190 |
+ </configuration> |
|
191 |
+ <configuration default="true" type="PyLettuceRunConfigurationType" factoryName="Lettuce"> |
|
192 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
193 |
+ <option name="PARENT_ENVS" value="true" /> |
|
194 |
+ <envs /> |
|
195 |
+ <option name="SDK_HOME" value="" /> |
|
196 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
197 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
198 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
199 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
200 |
+ <module name="tamron" /> |
|
201 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
202 |
+ <option name="ADDITIONAL_ARGS" value="" /> |
|
203 |
+ <method /> |
|
204 |
+ </configuration> |
|
205 |
+ <configuration default="true" type="Python.DjangoServer" factoryName="Django server"> |
|
206 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
207 |
+ <option name="PARENT_ENVS" value="true" /> |
|
208 |
+ <envs> |
|
209 |
+ <env name="PYTHONUNBUFFERED" value="1" /> |
|
210 |
+ </envs> |
|
211 |
+ <option name="SDK_HOME" value="" /> |
|
212 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
213 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
214 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
215 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
216 |
+ <module name="tamron" /> |
|
217 |
+ <option name="launchJavascriptDebuger" value="false" /> |
|
218 |
+ <option name="port" value="8000" /> |
|
219 |
+ <option name="host" value="" /> |
|
220 |
+ <option name="additionalOptions" value="" /> |
|
221 |
+ <option name="browserUrl" value="" /> |
|
222 |
+ <option name="runTestServer" value="false" /> |
|
223 |
+ <option name="runNoReload" value="false" /> |
|
224 |
+ <option name="useCustomRunCommand" value="false" /> |
|
225 |
+ <option name="customRunCommand" value="" /> |
|
226 |
+ <method /> |
|
227 |
+ </configuration> |
|
228 |
+ <configuration default="true" type="PythonConfigurationType" factoryName="Python"> |
|
229 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
230 |
+ <option name="PARENT_ENVS" value="true" /> |
|
231 |
+ <envs> |
|
232 |
+ <env name="PYTHONUNBUFFERED" value="1" /> |
|
233 |
+ </envs> |
|
234 |
+ <option name="SDK_HOME" value="" /> |
|
235 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
236 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
237 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
238 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
239 |
+ <module name="tamron" /> |
|
240 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
241 |
+ <option name="SCRIPT_NAME" value="" /> |
|
242 |
+ <option name="PARAMETERS" value="" /> |
|
243 |
+ <option name="SHOW_COMMAND_LINE" value="false" /> |
|
244 |
+ <method /> |
|
245 |
+ </configuration> |
|
246 |
+ <configuration default="true" type="Tox" factoryName="Tox"> |
|
247 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
248 |
+ <option name="PARENT_ENVS" value="true" /> |
|
249 |
+ <envs /> |
|
250 |
+ <option name="SDK_HOME" value="" /> |
|
251 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
252 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
253 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
254 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
255 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
256 |
+ <module name="tamron" /> |
|
257 |
+ <method /> |
|
258 |
+ </configuration> |
|
259 |
+ <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js"> |
|
260 |
+ <node-interpreter>project</node-interpreter> |
|
261 |
+ <node-options /> |
|
262 |
+ <gulpfile /> |
|
263 |
+ <tasks /> |
|
264 |
+ <arguments /> |
|
265 |
+ <envs /> |
|
266 |
+ <method /> |
|
267 |
+ </configuration> |
|
268 |
+ <configuration default="true" type="js.build_tools.npm" factoryName="npm"> |
|
269 |
+ <command value="run-script" /> |
|
270 |
+ <scripts /> |
|
271 |
+ <node-interpreter value="project" /> |
|
272 |
+ <envs /> |
|
273 |
+ <method /> |
|
274 |
+ </configuration> |
|
275 |
+ <configuration default="true" type="tests" factoryName="Attests"> |
|
276 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
277 |
+ <option name="PARENT_ENVS" value="true" /> |
|
278 |
+ <envs /> |
|
279 |
+ <option name="SDK_HOME" value="" /> |
|
280 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
281 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
282 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
283 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
284 |
+ <module name="tamron" /> |
|
285 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
286 |
+ <option name="SCRIPT_NAME" value="" /> |
|
287 |
+ <option name="CLASS_NAME" value="" /> |
|
288 |
+ <option name="METHOD_NAME" value="" /> |
|
289 |
+ <option name="FOLDER_NAME" value="" /> |
|
290 |
+ <option name="TEST_TYPE" value="TEST_SCRIPT" /> |
|
291 |
+ <option name="PATTERN" value="" /> |
|
292 |
+ <option name="USE_PATTERN" value="false" /> |
|
293 |
+ <method /> |
|
294 |
+ </configuration> |
|
295 |
+ <configuration default="true" type="tests" factoryName="Doctests"> |
|
296 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
297 |
+ <option name="PARENT_ENVS" value="true" /> |
|
298 |
+ <envs /> |
|
299 |
+ <option name="SDK_HOME" value="" /> |
|
300 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
301 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
302 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
303 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
304 |
+ <module name="tamron" /> |
|
305 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
306 |
+ <option name="SCRIPT_NAME" value="" /> |
|
307 |
+ <option name="CLASS_NAME" value="" /> |
|
308 |
+ <option name="METHOD_NAME" value="" /> |
|
309 |
+ <option name="FOLDER_NAME" value="" /> |
|
310 |
+ <option name="TEST_TYPE" value="TEST_SCRIPT" /> |
|
311 |
+ <option name="PATTERN" value="" /> |
|
312 |
+ <option name="USE_PATTERN" value="false" /> |
|
313 |
+ <method /> |
|
314 |
+ </configuration> |
|
315 |
+ <configuration default="true" type="tests" factoryName="Nosetests"> |
|
316 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
317 |
+ <option name="PARENT_ENVS" value="true" /> |
|
318 |
+ <envs /> |
|
319 |
+ <option name="SDK_HOME" value="" /> |
|
320 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
321 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
322 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
323 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
324 |
+ <module name="tamron" /> |
|
325 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
326 |
+ <option name="SCRIPT_NAME" value="" /> |
|
327 |
+ <option name="CLASS_NAME" value="" /> |
|
328 |
+ <option name="METHOD_NAME" value="" /> |
|
329 |
+ <option name="FOLDER_NAME" value="" /> |
|
330 |
+ <option name="TEST_TYPE" value="TEST_SCRIPT" /> |
|
331 |
+ <option name="PATTERN" value="" /> |
|
332 |
+ <option name="USE_PATTERN" value="false" /> |
|
333 |
+ <option name="PARAMS" value="" /> |
|
334 |
+ <option name="USE_PARAM" value="false" /> |
|
335 |
+ <method /> |
|
336 |
+ </configuration> |
|
337 |
+ <configuration default="true" type="tests" factoryName="Unittests"> |
|
338 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
339 |
+ <option name="PARENT_ENVS" value="true" /> |
|
340 |
+ <envs /> |
|
341 |
+ <option name="SDK_HOME" value="" /> |
|
342 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
343 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
344 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
345 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
346 |
+ <module name="tamron" /> |
|
347 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
348 |
+ <option name="SCRIPT_NAME" value="" /> |
|
349 |
+ <option name="CLASS_NAME" value="" /> |
|
350 |
+ <option name="METHOD_NAME" value="" /> |
|
351 |
+ <option name="FOLDER_NAME" value="" /> |
|
352 |
+ <option name="TEST_TYPE" value="TEST_SCRIPT" /> |
|
353 |
+ <option name="PATTERN" value="" /> |
|
354 |
+ <option name="USE_PATTERN" value="false" /> |
|
355 |
+ <option name="PUREUNITTEST" value="true" /> |
|
356 |
+ <option name="PARAMS" value="" /> |
|
357 |
+ <option name="USE_PARAM" value="false" /> |
|
358 |
+ <method /> |
|
359 |
+ </configuration> |
|
360 |
+ <configuration default="true" type="tests" factoryName="py.test"> |
|
361 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
362 |
+ <option name="PARENT_ENVS" value="true" /> |
|
363 |
+ <envs /> |
|
364 |
+ <option name="SDK_HOME" value="" /> |
|
365 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
366 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
367 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
368 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
369 |
+ <module name="tamron" /> |
|
370 |
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" /> |
|
371 |
+ <option name="SCRIPT_NAME" value="" /> |
|
372 |
+ <option name="CLASS_NAME" value="" /> |
|
373 |
+ <option name="METHOD_NAME" value="" /> |
|
374 |
+ <option name="FOLDER_NAME" value="" /> |
|
375 |
+ <option name="TEST_TYPE" value="TEST_SCRIPT" /> |
|
376 |
+ <option name="PATTERN" value="" /> |
|
377 |
+ <option name="USE_PATTERN" value="false" /> |
|
378 |
+ <option name="testToRun" value="" /> |
|
379 |
+ <option name="keywords" value="" /> |
|
380 |
+ <option name="params" value="" /> |
|
381 |
+ <option name="USE_PARAM" value="false" /> |
|
382 |
+ <option name="USE_KEYWORD" value="false" /> |
|
383 |
+ <method /> |
|
384 |
+ </configuration> |
|
385 |
+ <configuration default="false" name="tamron" type="Python.DjangoServer" factoryName="Django server"> |
|
386 |
+ <option name="INTERPRETER_OPTIONS" value="" /> |
|
387 |
+ <option name="PARENT_ENVS" value="true" /> |
|
388 |
+ <envs> |
|
389 |
+ <env name="PYTHONUNBUFFERED" value="1" /> |
|
390 |
+ </envs> |
|
391 |
+ <option name="SDK_HOME" value="" /> |
|
392 |
+ <option name="WORKING_DIRECTORY" value="" /> |
|
393 |
+ <option name="IS_MODULE_SDK" value="false" /> |
|
394 |
+ <option name="ADD_CONTENT_ROOTS" value="true" /> |
|
395 |
+ <option name="ADD_SOURCE_ROOTS" value="true" /> |
|
396 |
+ <module name="tamron" /> |
|
397 |
+ <option name="launchJavascriptDebuger" value="false" /> |
|
398 |
+ <option name="port" value="8000" /> |
|
399 |
+ <option name="host" value="" /> |
|
400 |
+ <option name="additionalOptions" value="" /> |
|
401 |
+ <option name="browserUrl" value="" /> |
|
402 |
+ <option name="runTestServer" value="false" /> |
|
403 |
+ <option name="runNoReload" value="false" /> |
|
404 |
+ <option name="useCustomRunCommand" value="false" /> |
|
405 |
+ <option name="customRunCommand" value="" /> |
|
406 |
+ <method /> |
|
407 |
+ </configuration> |
|
408 |
+ <list size="1"> |
|
409 |
+ <item index="0" class="java.lang.String" itemvalue="Django server.tamron" /> |
|
410 |
+ </list> |
|
411 |
+ </component> |
|
412 |
+ <component name="ShelveChangesManager" show_recycled="false"> |
|
413 |
+ <option name="remove_strategy" value="false" /> |
|
414 |
+ </component> |
|
415 |
+ <component name="TaskManager"> |
|
416 |
+ <task active="true" id="Default" summary="Default task"> |
|
417 |
+ <changelist id="8287082c-5144-4790-9da1-578e292318f7" name="Default" comment="" /> |
|
418 |
+ <created>1497849391019</created> |
|
419 |
+ <option name="number" value="Default" /> |
|
420 |
+ <option name="presentableId" value="Default" /> |
|
421 |
+ <updated>1497849391019</updated> |
|
422 |
+ </task> |
|
423 |
+ <servers /> |
|
424 |
+ </component> |
|
425 |
+ <component name="ToolWindowManager"> |
|
426 |
+ <frame x="65" y="24" width="1301" height="744" extended-state="6" /> |
|
427 |
+ <editor active="false" /> |
|
428 |
+ <layout> |
|
429 |
+ <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.16756341" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" /> |
|
430 |
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" /> |
|
431 |
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" /> |
|
432 |
+ <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> |
|
433 |
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> |
|
434 |
+ <window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> |
|
435 |
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> |
|
436 |
+ <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> |
|
437 |
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" /> |
|
438 |
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" /> |
|
439 |
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> |
|
440 |
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> |
|
441 |
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" /> |
|
442 |
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> |
|
443 |
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" /> |
|
444 |
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> |
|
445 |
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> |
|
446 |
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> |
|
447 |
+ </layout> |
|
448 |
+ </component> |
|
449 |
+ <component name="Vcs.Log.UiProperties"> |
|
450 |
+ <option name="RECENTLY_FILTERED_USER_GROUPS"> |
|
451 |
+ <collection /> |
|
452 |
+ </option> |
|
453 |
+ <option name="RECENTLY_FILTERED_BRANCH_GROUPS"> |
|
454 |
+ <collection /> |
|
455 |
+ </option> |
|
456 |
+ </component> |
|
457 |
+ <component name="VcsContentAnnotationSettings"> |
|
458 |
+ <option name="myLimit" value="2678400000" /> |
|
459 |
+ </component> |
|
460 |
+ <component name="XDebuggerManager"> |
|
461 |
+ <breakpoint-manager> |
|
462 |
+ <option name="time" value="2" /> |
|
463 |
+ </breakpoint-manager> |
|
464 |
+ <watches-manager /> |
|
465 |
+ </component> |
|
466 |
+ <component name="editorHistoryManager"> |
|
467 |
+ <entry file="file://$PROJECT_DIR$/page/models.py"> |
|
468 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
469 |
+ <state relative-caret-position="0"> |
|
470 |
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" /> |
|
471 |
+ </state> |
|
472 |
+ </provider> |
|
473 |
+ </entry> |
|
474 |
+ <entry file="file://$PROJECT_DIR$/account/admin.py"> |
|
475 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
476 |
+ <state relative-caret-position="165"> |
|
477 |
+ <caret line="13" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="23" selection-end-column="0" /> |
|
478 |
+ </state> |
|
479 |
+ </provider> |
|
480 |
+ </entry> |
|
481 |
+ <entry file="file://$PROJECT_DIR$/tamron/basemodels.py"> |
|
482 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
483 |
+ <state relative-caret-position="105"> |
|
484 |
+ <caret line="7" column="94" selection-start-line="7" selection-start-column="79" selection-end-line="7" selection-end-column="94" /> |
|
485 |
+ </state> |
|
486 |
+ </provider> |
|
487 |
+ </entry> |
|
488 |
+ <entry file="file://$PROJECT_DIR$/integral/admin.py"> |
|
489 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
490 |
+ <state relative-caret-position="150"> |
|
491 |
+ <caret line="10" column="38" selection-start-line="10" selection-start-column="38" selection-end-line="10" selection-end-column="38" /> |
|
492 |
+ </state> |
|
493 |
+ </provider> |
|
494 |
+ </entry> |
|
495 |
+ <entry file="file://$PROJECT_DIR$/product/admin.py"> |
|
496 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
497 |
+ <state relative-caret-position="390"> |
|
498 |
+ <caret line="26" column="0" selection-start-line="26" selection-start-column="0" selection-end-line="26" selection-end-column="60" /> |
|
499 |
+ </state> |
|
500 |
+ </provider> |
|
501 |
+ </entry> |
|
502 |
+ <entry file="file://$PROJECT_DIR$/integral/views.py"> |
|
503 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
504 |
+ <state relative-caret-position="60"> |
|
505 |
+ <caret line="4" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="4" selection-end-column="0" /> |
|
506 |
+ </state> |
|
507 |
+ </provider> |
|
508 |
+ </entry> |
|
509 |
+ <entry file="file://$PROJECT_DIR$/page/views.py"> |
|
510 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
511 |
+ <state relative-caret-position="60"> |
|
512 |
+ <caret line="4" column="0" selection-start-line="4" selection-start-column="0" selection-end-line="4" selection-end-column="0" /> |
|
513 |
+ </state> |
|
514 |
+ </provider> |
|
515 |
+ </entry> |
|
516 |
+ <entry file="file://$PROJECT_DIR$/product/models.py"> |
|
517 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
518 |
+ <state relative-caret-position="308"> |
|
519 |
+ <caret line="43" column="104" selection-start-line="43" selection-start-column="104" selection-end-line="43" selection-end-column="104" /> |
|
520 |
+ </state> |
|
521 |
+ </provider> |
|
522 |
+ </entry> |
|
523 |
+ <entry file="file://$PROJECT_DIR$/integral/models.py"> |
|
524 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
525 |
+ <state relative-caret-position="360"> |
|
526 |
+ <caret line="24" column="30" selection-start-line="24" selection-start-column="30" selection-end-line="24" selection-end-column="30" /> |
|
527 |
+ </state> |
|
528 |
+ </provider> |
|
529 |
+ </entry> |
|
530 |
+ <entry file="file://$PROJECT_DIR$/tamron/settings.py"> |
|
531 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
532 |
+ <state relative-caret-position="312"> |
|
533 |
+ <caret line="200" column="6" selection-start-line="200" selection-start-column="0" selection-end-line="200" selection-end-column="6" /> |
|
534 |
+ <folding /> |
|
535 |
+ </state> |
|
536 |
+ </provider> |
|
537 |
+ </entry> |
|
538 |
+ <entry file="file://$PROJECT_DIR$/tamron/local_settings.py"> |
|
539 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
540 |
+ <state relative-caret-position="420"> |
|
541 |
+ <caret line="28" column="32" selection-start-line="28" selection-start-column="32" selection-end-line="28" selection-end-column="32" /> |
|
542 |
+ </state> |
|
543 |
+ </provider> |
|
544 |
+ </entry> |
|
545 |
+ <entry file="file://$PROJECT_DIR$/api/urls.py"> |
|
546 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
547 |
+ <state relative-caret-position="120"> |
|
548 |
+ <caret line="8" column="44" selection-start-line="8" selection-start-column="44" selection-end-line="8" selection-end-column="44" /> |
|
549 |
+ </state> |
|
550 |
+ </provider> |
|
551 |
+ </entry> |
|
552 |
+ <entry file="file://$PROJECT_DIR$/page/templates/page/clerk_oauth.html"> |
|
553 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
554 |
+ <state relative-caret-position="360"> |
|
555 |
+ <caret line="57" column="18" selection-start-line="25" selection-start-column="12" selection-end-line="57" selection-end-column="18" /> |
|
556 |
+ <folding /> |
|
557 |
+ </state> |
|
558 |
+ </provider> |
|
559 |
+ </entry> |
|
560 |
+ <entry file="file://$PROJECT_DIR$/page/templates/page/clerk_sale.html"> |
|
561 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
562 |
+ <state relative-caret-position="273"> |
|
563 |
+ <caret line="160" column="0" selection-start-line="160" selection-start-column="0" selection-end-line="160" selection-end-column="0" /> |
|
564 |
+ <folding /> |
|
565 |
+ </state> |
|
566 |
+ </provider> |
|
567 |
+ </entry> |
|
568 |
+ <entry file="file://$PROJECT_DIR$/utils/error/errno_utils.py"> |
|
569 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
570 |
+ <state relative-caret-position="75"> |
|
571 |
+ <caret line="5" column="26" selection-start-line="5" selection-start-column="6" selection-end-line="5" selection-end-column="26" /> |
|
572 |
+ </state> |
|
573 |
+ </provider> |
|
574 |
+ </entry> |
|
575 |
+ <entry file="file://$PROJECT_DIR$/account/models.py"> |
|
576 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
577 |
+ <state relative-caret-position="521"> |
|
578 |
+ <caret line="88" column="38" selection-start-line="88" selection-start-column="38" selection-end-line="88" selection-end-column="38" /> |
|
579 |
+ </state> |
|
580 |
+ </provider> |
|
581 |
+ </entry> |
|
582 |
+ <entry file="file://$PROJECT_DIR$/tamron/urls.py"> |
|
583 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
584 |
+ <state relative-caret-position="465"> |
|
585 |
+ <caret line="31" column="55" selection-start-line="31" selection-start-column="55" selection-end-line="31" selection-end-column="55" /> |
|
586 |
+ </state> |
|
587 |
+ </provider> |
|
588 |
+ </entry> |
|
589 |
+ <entry file="file://$PROJECT_DIR$/page/sale_views.py"> |
|
590 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
591 |
+ <state relative-caret-position="311"> |
|
592 |
+ <caret line="97" column="18" selection-start-line="97" selection-start-column="10" selection-end-line="97" selection-end-column="18" /> |
|
593 |
+ </state> |
|
594 |
+ </provider> |
|
595 |
+ </entry> |
|
596 |
+ <entry file="file://$PROJECT_DIR$/page/info_views.py"> |
|
597 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
598 |
+ <state relative-caret-position="300"> |
|
599 |
+ <caret line="20" column="42" selection-start-line="20" selection-start-column="42" selection-end-line="20" selection-end-column="42" /> |
|
600 |
+ </state> |
|
601 |
+ </provider> |
|
602 |
+ </entry> |
|
603 |
+ <entry file="file://$PROJECT_DIR$/page/oauth_views.py"> |
|
604 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
605 |
+ <state relative-caret-position="135"> |
|
606 |
+ <caret line="9" column="37" selection-start-line="9" selection-start-column="31" selection-end-line="9" selection-end-column="37" /> |
|
607 |
+ </state> |
|
608 |
+ </provider> |
|
609 |
+ </entry> |
|
610 |
+ <entry file="file://$PROJECT_DIR$/page/templates/page/clerk_info.html"> |
|
611 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
612 |
+ <state relative-caret-position="48"> |
|
613 |
+ <caret line="44" column="0" selection-start-line="44" selection-start-column="0" selection-end-line="44" selection-end-column="0" /> |
|
614 |
+ </state> |
|
615 |
+ </provider> |
|
616 |
+ </entry> |
|
617 |
+ <entry file="file://$PROJECT_DIR$/tamron/uwsgi.bak/tamron.ini"> |
|
618 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
619 |
+ <state relative-caret-position="255"> |
|
620 |
+ <caret line="17" column="61" selection-start-line="17" selection-start-column="61" selection-end-line="17" selection-end-column="61" /> |
|
621 |
+ <folding /> |
|
622 |
+ </state> |
|
623 |
+ </provider> |
|
624 |
+ </entry> |
|
625 |
+ <entry file="file://$PROJECT_DIR$/tamron/uwsgi.bak/tamron_nginx.conf"> |
|
626 |
+ <provider selected="true" editor-type-id="text-editor"> |
|
627 |
+ <state relative-caret-position="480"> |
|
628 |
+ <caret line="32" column="50" selection-start-line="32" selection-start-column="50" selection-end-line="32" selection-end-column="50" /> |
|
629 |
+ <folding /> |
|
630 |
+ </state> |
|
631 |
+ </provider> |
|
632 |
+ </entry> |
|
633 |
+ </component> |
|
634 |
+</project> |
@@ -0,0 +1,8 @@ |
||
1 |
+# See the menu of settings available here: |
|
2 |
+# https://github.com/timothycrosley/isort/wiki/isort-Settings |
|
3 |
+ |
|
4 |
+[settings] |
|
5 |
+indent=' ' |
|
6 |
+line_length=120 |
|
7 |
+lines_after_imports=2 |
|
8 |
+skip=migrations |
@@ -0,0 +1,23 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.contrib import admin |
|
4 |
+ |
|
5 |
+from account.models import FranchiserInfo, SaleclerkInfo |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class FranchiserInfoAdmin(admin.ModelAdmin): |
|
9 |
+ readonly_fields = ('franchiser_id', ) |
|
10 |
+ list_display = ('franchiser_id', 'franchiser_name', 'franchiser_addr', 'franchiser_phone', 'franchiser_boss_name', 'franchiser_boss_phone', 'status', 'created_at', 'updated_at') |
|
11 |
+ search_fields = ('franchiser_id', 'franchiser_name', 'franchiser_addr', 'franchiser_phone', 'franchiser_boss_name', 'franchiser_boss_phone') |
|
12 |
+ list_filter = ('status', ) |
|
13 |
+ |
|
14 |
+ |
|
15 |
+class SaleclerkInfoAdmin(admin.ModelAdmin): |
|
16 |
+ readonly_fields = ('franchiser_id', ) |
|
17 |
+ list_display = ('franchiser_id', 'clerk_id', 'clerk_name', 'clerk_sex', 'clerk_phone', 'user_status', 'status', 'created_at', 'updated_at') |
|
18 |
+ search_fields = ('franchiser_id', 'clerk_id', 'clerk_name', 'clerk_phone') |
|
19 |
+ list_filter = ('user_status', 'status') |
|
20 |
+ |
|
21 |
+ |
|
22 |
+admin.site.register(FranchiserInfo, FranchiserInfoAdmin) |
|
23 |
+admin.site.register(SaleclerkInfo, SaleclerkInfoAdmin) |
@@ -0,0 +1,55 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+import shortuuidfield.fields |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.CreateModel( |
|
15 |
+ name='FranchiserInfo', |
|
16 |
+ fields=[ |
|
17 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
18 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
19 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
20 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
21 |
+ ('franchiser_id', shortuuidfield.fields.ShortUUIDField(editable=False, max_length=22, blank=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', unique=True, db_index=True)), |
|
22 |
+ ('franchiser_name', models.CharField(help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=255, null=True, verbose_name='franchiser_name', blank=True)), |
|
23 |
+ ('franchiser_addr', models.CharField(help_text='\u7ecf\u9500\u5546\u5730\u5740', max_length=255, null=True, verbose_name='franchiser_addr', blank=True)), |
|
24 |
+ ('franchiser_phone', models.CharField(help_text='\u7ecf\u9500\u5546\u8054\u7cfb\u7535\u8bdd', max_length=255, null=True, verbose_name='franchiser_phone', blank=True)), |
|
25 |
+ ('franchiser_boss_name', models.CharField(help_text='\u7ecf\u9500\u5546\u8001\u677f\u540d\u79f0', max_length=255, null=True, verbose_name='franchiser_boss_name', blank=True)), |
|
26 |
+ ('franchiser_boss_phone', models.CharField(help_text='\u7ecf\u9500\u5546\u8001\u677f\u8054\u7cfb\u7535\u8bdd', max_length=255, null=True, verbose_name='franchiser_boss_phone', blank=True)), |
|
27 |
+ ], |
|
28 |
+ options={ |
|
29 |
+ 'verbose_name': 'franchiserinfo', |
|
30 |
+ 'verbose_name_plural': 'franchiserinfo', |
|
31 |
+ }, |
|
32 |
+ ), |
|
33 |
+ migrations.CreateModel( |
|
34 |
+ name='SaleclerkInfo', |
|
35 |
+ fields=[ |
|
36 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
37 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
38 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
39 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
40 |
+ ('franchiser_id', models.CharField(max_length=255, blank=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='franchiser_id', db_index=True)), |
|
41 |
+ ('clerk_id', shortuuidfield.fields.ShortUUIDField(editable=False, max_length=22, blank=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', unique=True, db_index=True)), |
|
42 |
+ ('clerk_name', models.CharField(help_text='\u5e97\u5458\u540d\u79f0', max_length=255, null=True, verbose_name='clerk_name', blank=True)), |
|
43 |
+ ('clerk_sex', models.IntegerField(default=1, help_text='\u5e97\u5458\u6027\u522b', verbose_name='clerk_sex', choices=[(1, '\u7537'), (0, '\u5973')])), |
|
44 |
+ ('clerk_phone', models.CharField(help_text='\u5e97\u5458\u8054\u7cfb\u7535\u8bdd', max_length=255, null=True, verbose_name='clerk_phone', blank=True)), |
|
45 |
+ ('openid', models.CharField(null=True, max_length=255, blank=True, help_text='\u5fae\u4fe1 OpenID', unique=True, verbose_name='openid', db_index=True)), |
|
46 |
+ ('unionid', models.CharField(null=True, max_length=255, blank=True, help_text='\u5fae\u4fe1 UnionID', unique=True, verbose_name='unionid', db_index=True)), |
|
47 |
+ ('user_status', models.IntegerField(default=0, verbose_name='user_status', choices=[(-1, '\u5df2\u62d2\u7edd'), (0, '\u672a\u9a8c\u8bc1'), (1, '\u5df2\u6fc0\u6d3b'), (2, '\u5df2\u7981\u7528'), (3, '\u5df2\u5220\u9664'), (10, '\u5df2\u5206\u914d')])), |
|
48 |
+ ('refused_reason', models.TextField(help_text='\u5ba1\u6838\u62d2\u7edd\u539f\u56e0', null=True, verbose_name='refused_reason', blank=True)), |
|
49 |
+ ], |
|
50 |
+ options={ |
|
51 |
+ 'verbose_name': 'saleclerkinfo', |
|
52 |
+ 'verbose_name_plural': 'saleclerkinfo', |
|
53 |
+ }, |
|
54 |
+ ), |
|
55 |
+ ] |
@@ -0,0 +1,33 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('account', '0001_initial'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.AlterModelOptions( |
|
15 |
+ name='franchiserinfo', |
|
16 |
+ options={'verbose_name': '\u7ecf\u9500\u5546\u4fe1\u606f\u8868', 'verbose_name_plural': '\u7ecf\u9500\u5546\u4fe1\u606f\u8868'}, |
|
17 |
+ ), |
|
18 |
+ migrations.AddField( |
|
19 |
+ model_name='saleclerkinfo', |
|
20 |
+ name='integral', |
|
21 |
+ field=models.IntegerField(default=0, help_text='\u79ef\u5206', verbose_name='integral'), |
|
22 |
+ ), |
|
23 |
+ migrations.AlterField( |
|
24 |
+ model_name='saleclerkinfo', |
|
25 |
+ name='clerk_sex', |
|
26 |
+ field=models.IntegerField(default=1, help_text='\u5e97\u5458\u6027\u522b', db_index=True, verbose_name='clerk_sex', choices=[(1, '\u7537'), (0, '\u5973')]), |
|
27 |
+ ), |
|
28 |
+ migrations.AlterField( |
|
29 |
+ model_name='saleclerkinfo', |
|
30 |
+ name='user_status', |
|
31 |
+ field=models.IntegerField(default=0, help_text='\u7528\u6237\u72b6\u6001', db_index=True, verbose_name='user_status', choices=[(-1, '\u5df2\u62d2\u7edd'), (0, '\u672a\u9a8c\u8bc1'), (1, '\u5df2\u6fc0\u6d3b'), (2, '\u5df2\u7981\u7528'), (3, '\u5df2\u5220\u9664'), (10, '\u5df2\u5206\u914d')]), |
|
32 |
+ ), |
|
33 |
+ ] |
@@ -0,0 +1,19 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('account', '0002_auto_20170619_1635'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.AddField( |
|
15 |
+ model_name='saleclerkinfo', |
|
16 |
+ name='franchiser_name', |
|
17 |
+ field=models.CharField(help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=255, null=True, verbose_name='franchiser_name', blank=True), |
|
18 |
+ ), |
|
19 |
+ ] |
@@ -0,0 +1,92 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.db import models |
|
4 |
+from django.utils.translation import ugettext_lazy as _ |
|
5 |
+from shortuuidfield import ShortUUIDField |
|
6 |
+ |
|
7 |
+from tamron.basemodels import CreateUpdateMixin |
|
8 |
+ |
|
9 |
+ |
|
10 |
+class FranchiserInfo(CreateUpdateMixin): |
|
11 |
+ franchiser_id = ShortUUIDField(_(u'franchiser_id'), max_length=255, help_text=u'经销商唯一标识', db_index=True, unique=True) |
|
12 |
+ franchiser_name = models.CharField(_(u'franchiser_name'), max_length=255, blank=True, null=True, help_text=u'经销商名称') |
|
13 |
+ franchiser_addr = models.CharField(_(u'franchiser_addr'), max_length=255, blank=True, null=True, help_text=u'经销商地址') |
|
14 |
+ franchiser_phone = models.CharField(_(u'franchiser_phone'), max_length=255, blank=True, null=True, help_text=u'经销商联系电话') |
|
15 |
+ franchiser_boss_name = models.CharField(_(u'franchiser_boss_name'), max_length=255, blank=True, null=True, help_text=u'经销商老板名称') |
|
16 |
+ franchiser_boss_phone = models.CharField(_(u'franchiser_boss_phone'), max_length=255, blank=True, null=True, help_text=u'经销商老板联系电话') |
|
17 |
+ |
|
18 |
+ class Meta: |
|
19 |
+ verbose_name = _(u'经销商信息表') |
|
20 |
+ verbose_name_plural = _(u'经销商信息表') |
|
21 |
+ |
|
22 |
+ def __unicode__(self): |
|
23 |
+ return unicode(self.pk) |
|
24 |
+ |
|
25 |
+ @property |
|
26 |
+ def data(self): |
|
27 |
+ return { |
|
28 |
+ 'franchiser_id': self.franchiser_id, |
|
29 |
+ 'franchiser_name': self.franchiser_name, |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+ |
|
33 |
+class SaleclerkInfo(CreateUpdateMixin): |
|
34 |
+ MALE = 1 |
|
35 |
+ FEMALE = 0 |
|
36 |
+ |
|
37 |
+ SEX_TYPE = ( |
|
38 |
+ (MALE, u'男'), |
|
39 |
+ (FEMALE, u'女'), |
|
40 |
+ ) |
|
41 |
+ |
|
42 |
+ REFUSED = -1 |
|
43 |
+ UNVERIFIED = 0 |
|
44 |
+ ACTIVATED = 1 |
|
45 |
+ DISABLED = 2 |
|
46 |
+ DELETED = 3 |
|
47 |
+ ASSIGN = 10 |
|
48 |
+ |
|
49 |
+ USER_STATUS = ( |
|
50 |
+ (REFUSED, u'已拒绝'), |
|
51 |
+ (UNVERIFIED, u'未验证'), |
|
52 |
+ (ACTIVATED, u'已激活'), |
|
53 |
+ (DISABLED, u'已禁用'), |
|
54 |
+ (DELETED, u'已删除'), |
|
55 |
+ (ASSIGN, u'已分配'), |
|
56 |
+ ) |
|
57 |
+ |
|
58 |
+ franchiser_id = models.CharField(_(u'franchiser_id'), max_length=255, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) |
|
59 |
+ franchiser_name = models.CharField(_(u'franchiser_name'), max_length=255, blank=True, null=True, help_text=u'经销商名称') |
|
60 |
+ clerk_id = ShortUUIDField(_(u'clerk_id'), max_length=255, help_text=u'店员唯一标识', db_index=True, unique=True) |
|
61 |
+ clerk_name = models.CharField(_(u'clerk_name'), max_length=255, blank=True, null=True, help_text=u'店员名称') |
|
62 |
+ clerk_sex = models.IntegerField(_(u'clerk_sex'), choices=SEX_TYPE, default=MALE, help_text=u'店员性别', db_index=True) |
|
63 |
+ clerk_phone = models.CharField(_(u'clerk_phone'), max_length=255, blank=True, null=True, help_text=u'店员联系电话') |
|
64 |
+ |
|
65 |
+ openid = models.CharField(_(u'openid'), max_length=255, blank=True, null=True, help_text=u'微信 OpenID', db_index=True, unique=True) |
|
66 |
+ unionid = models.CharField(_(u'unionid'), max_length=255, blank=True, null=True, help_text=u'微信 UnionID', db_index=True, unique=True) |
|
67 |
+ |
|
68 |
+ integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分') |
|
69 |
+ |
|
70 |
+ user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'用户状态', db_index=True) |
|
71 |
+ refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因') |
|
72 |
+ |
|
73 |
+ class Meta: |
|
74 |
+ verbose_name = _(u'saleclerkinfo') |
|
75 |
+ verbose_name_plural = _(u'saleclerkinfo') |
|
76 |
+ |
|
77 |
+ def __unicode__(self): |
|
78 |
+ return unicode(self.pk) |
|
79 |
+ |
|
80 |
+ @property |
|
81 |
+ def data(self): |
|
82 |
+ return { |
|
83 |
+ 'franchiser_id': self.franchiser_id, |
|
84 |
+ 'franchiser_name': self.franchiser_name, |
|
85 |
+ 'clerk_id': self.clerk_id, |
|
86 |
+ 'clerk_name': self.clerk_name, |
|
87 |
+ 'clerk_sex': self.clerk_sex, |
|
88 |
+ 'clerk_phone': self.clerk_phone, |
|
89 |
+ 'integral': self.integral, |
|
90 |
+ 'status': self.user_status, |
|
91 |
+ 'refused_reason': self.refused_reason, |
|
92 |
+ } |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.test import TestCase |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your tests here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.shortcuts import render |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your views here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.contrib import admin |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Register your models here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.db import models |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your models here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.test import TestCase |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your tests here. |
@@ -0,0 +1,11 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.conf.urls import url |
|
4 |
+ |
|
5 |
+from page import oauth_views, sale_views |
|
6 |
+ |
|
7 |
+ |
|
8 |
+urlpatterns = [ |
|
9 |
+ url(r'^clerk/submit$', oauth_views.clerk_submit_api, name='clerk_submit_api'), # 店员信息提交 |
|
10 |
+ url(r'^clerk/sale/submit$', sale_views.clerk_sale_submit_api, name='clerk_sale_submit_api'), # 店员销售信息提交 |
|
11 |
+] |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.shortcuts import render |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your views here. |
@@ -0,0 +1,9 @@ |
||
1 |
+#!/bin/bash |
|
2 |
+ |
|
3 |
+echo '>> iSort' |
|
4 |
+./isort.sh |
|
5 |
+echo |
|
6 |
+ |
|
7 |
+echo '>> PEP8' |
|
8 |
+./pep8.sh |
|
9 |
+echo |
@@ -0,0 +1,15 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.contrib import admin |
|
4 |
+ |
|
5 |
+from integral.models import SaleclerkIntegralIncomeExpensesInfo |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class SaleclerkIntegralIncomeExpensesInfoAdmin(admin.ModelAdmin): |
|
9 |
+ readonly_fields = ('franchiser_id', 'clerk_id', 'type', 'code', 'integral', 'left_integral') |
|
10 |
+ list_display = ('franchiser_id', 'clerk_id', 'type', 'code', 'integral', 'left_integral', 'remark', 'status', 'created_at', 'updated_at') |
|
11 |
+ search_fields = ('code', 'remark') |
|
12 |
+ list_filter = ('franchiser_id', 'type', 'status') |
|
13 |
+ |
|
14 |
+ |
|
15 |
+admin.site.register(SaleclerkIntegralIncomeExpensesInfo, SaleclerkIntegralIncomeExpensesInfoAdmin) |
@@ -0,0 +1,33 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ] |
|
11 |
+ |
|
12 |
+ operations = [ |
|
13 |
+ migrations.CreateModel( |
|
14 |
+ name='SaleclerkIntegralIncomeExpensesInfo', |
|
15 |
+ fields=[ |
|
16 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
17 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
18 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
19 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
20 |
+ ('franchiser_id', models.CharField(max_length=255, blank=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='franchiser_id', db_index=True)), |
|
21 |
+ ('clerk_id', models.CharField(max_length=255, blank=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='clerk_id', db_index=True)), |
|
22 |
+ ('type', models.IntegerField(default=0, help_text='\u6536\u652f\u7c7b\u522b', db_index=True, verbose_name='type', choices=[(0, '\u6536\u5165'), (1, '\u652f\u51fa'), (2, '\u89e3\u51bb')])), |
|
23 |
+ ('code', models.CharField(help_text='\u673a\u8eab\u7801', max_length=255, null=True, verbose_name='code', blank=True)), |
|
24 |
+ ('integral', models.IntegerField(default=0, help_text='\u589e\u51cf\u79ef\u5206', verbose_name='integral')), |
|
25 |
+ ('left_integral', models.IntegerField(default=0, help_text='\u79ef\u5206\u589e\u51cf\u540e\u6570\u91cf(\u5206)', verbose_name='left_integral')), |
|
26 |
+ ('remark', models.CharField(help_text='\u5907\u6ce8', max_length=255, null=True, verbose_name='remark', blank=True)), |
|
27 |
+ ], |
|
28 |
+ options={ |
|
29 |
+ 'verbose_name': 'saleclerkintegralincomeexpensesinfo', |
|
30 |
+ 'verbose_name_plural': 'saleclerkintegralincomeexpensesinfo', |
|
31 |
+ }, |
|
32 |
+ ), |
|
33 |
+ ] |
@@ -0,0 +1,19 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('integral', '0001_initial'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.AlterField( |
|
15 |
+ model_name='saleclerkintegralincomeexpensesinfo', |
|
16 |
+ name='code', |
|
17 |
+ field=models.CharField(max_length=255, blank=True, help_text='\u673a\u8eab\u7801', null=True, verbose_name='code', db_index=True), |
|
18 |
+ ), |
|
19 |
+ ] |
@@ -0,0 +1,36 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.db import models |
|
4 |
+from django.utils.translation import ugettext_lazy as _ |
|
5 |
+ |
|
6 |
+from tamron.basemodels import CreateUpdateMixin |
|
7 |
+ |
|
8 |
+ |
|
9 |
+class SaleclerkIntegralIncomeExpensesInfo(CreateUpdateMixin): |
|
10 |
+ INCOME = 0 |
|
11 |
+ EXPENSE = 1 |
|
12 |
+ UNFREEZE = 2 |
|
13 |
+ |
|
14 |
+ TYPE = ( |
|
15 |
+ (INCOME, u'收入'), |
|
16 |
+ (EXPENSE, u'支出'), |
|
17 |
+ (UNFREEZE, u'解冻'), |
|
18 |
+ ) |
|
19 |
+ |
|
20 |
+ franchiser_id = models.CharField(_(u'franchiser_id'), max_length=255, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) |
|
21 |
+ clerk_id = models.CharField(_(u'clerk_id'), max_length=255, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) |
|
22 |
+ |
|
23 |
+ type = models.IntegerField(_(u'type'), choices=TYPE, default=INCOME, help_text=u'收支类别', db_index=True) |
|
24 |
+ |
|
25 |
+ code = models.CharField(_(u'code'), max_length=255, blank=True, null=True, help_text=u'机身码', db_index=True) |
|
26 |
+ integral = models.IntegerField(_(u'integral'), default=0, help_text=u'增减积分') |
|
27 |
+ left_integral = models.IntegerField(_(u'left_integral'), default=0, help_text=u'积分增减后数量(分)') |
|
28 |
+ |
|
29 |
+ remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注') |
|
30 |
+ |
|
31 |
+ class Meta: |
|
32 |
+ verbose_name = _(u'saleclerkintegralincomeexpensesinfo') |
|
33 |
+ verbose_name_plural = _(u'saleclerkintegralincomeexpensesinfo') |
|
34 |
+ |
|
35 |
+ def __unicode__(self): |
|
36 |
+ return unicode(self.pk) |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.test import TestCase |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your tests here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.shortcuts import render |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your views here. |
@@ -0,0 +1,3 @@ |
||
1 |
+#!/bin/bash |
|
2 |
+ |
|
3 |
+isort -rc -sp . . |
@@ -0,0 +1,11 @@ |
||
1 |
+#!/usr/bin/env python |
|
2 |
+import os |
|
3 |
+import sys |
|
4 |
+ |
|
5 |
+ |
|
6 |
+if __name__ == "__main__": |
|
7 |
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tamron.settings") |
|
8 |
+ |
|
9 |
+ from django.core.management import execute_from_command_line |
|
10 |
+ |
|
11 |
+ execute_from_command_line(sys.argv) |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.contrib import admin |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Register your models here. |
@@ -0,0 +1,22 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from __future__ import division |
|
4 |
+ |
|
5 |
+from django.conf import settings |
|
6 |
+from django.shortcuts import render |
|
7 |
+ |
|
8 |
+from account.models import SaleclerkInfo |
|
9 |
+ |
|
10 |
+ |
|
11 |
+def clerk_info_oauth(request): |
|
12 |
+ unionid = request.GET.get('unionid', '') |
|
13 |
+ |
|
14 |
+ try: |
|
15 |
+ clerk = SaleclerkInfo.objects.get(unionid=unionid) |
|
16 |
+ except SaleclerkInfo.DoesNotExist: |
|
17 |
+ clerk = None |
|
18 |
+ |
|
19 |
+ return render(request, 'page/clerk_info.html', { |
|
20 |
+ 'domain': settings.DOMAIN, |
|
21 |
+ 'clerk_info': clerk and clerk.data, |
|
22 |
+ }) |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.db import models |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your models here. |
@@ -0,0 +1,70 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from __future__ import division |
|
4 |
+ |
|
5 |
+from django.conf import settings |
|
6 |
+from django.db import transaction |
|
7 |
+from django.shortcuts import render |
|
8 |
+from logit import logit |
|
9 |
+ |
|
10 |
+from account.models import FranchiserInfo, SaleclerkInfo |
|
11 |
+from utils.error.errno_utils import FranchiserStatusCode, SaleclerkStatusCode |
|
12 |
+from utils.error.response_utils import response |
|
13 |
+ |
|
14 |
+ |
|
15 |
+def clerk_oauth(request): |
|
16 |
+ unionid = request.GET.get('unionid', '') |
|
17 |
+ |
|
18 |
+ chisers = FranchiserInfo.objects.filter(status=True) |
|
19 |
+ chisers = [chiser.data for chiser in chisers] |
|
20 |
+ |
|
21 |
+ try: |
|
22 |
+ clerk = SaleclerkInfo.objects.get(unionid=unionid) |
|
23 |
+ except SaleclerkInfo.DoesNotExist: |
|
24 |
+ clerk = None |
|
25 |
+ |
|
26 |
+ return render(request, 'page/clerk_oauth.html', { |
|
27 |
+ 'domain': settings.DOMAIN, |
|
28 |
+ 'chisers': chisers, |
|
29 |
+ 'clerk_info': clerk and clerk.data, |
|
30 |
+ 'modified': bool((not clerk) or (clerk and clerk.user_status in [SaleclerkInfo.UNVERIFIED, SaleclerkInfo.REFUSED])), # 是否可以更改信息 |
|
31 |
+ }) |
|
32 |
+ |
|
33 |
+ |
|
34 |
+@logit |
|
35 |
+@transaction.atomic |
|
36 |
+def clerk_submit_api(request): |
|
37 |
+ """ 店员授权信息提交 """ |
|
38 |
+ unionid = request.POST.get('unionid', '') |
|
39 |
+ openid = request.POST.get('openid', '') |
|
40 |
+ phone = request.POST.get('phone', '') |
|
41 |
+ chiser = request.POST.get('chiser', '') |
|
42 |
+ |
|
43 |
+ if SaleclerkInfo.objects.filter(clerk_phone=phone).exclude(unionid=unionid).exists(): |
|
44 |
+ return response(SaleclerkStatusCode.CLERK_PHONE_ALREADY_EXISTS) |
|
45 |
+ |
|
46 |
+ try: |
|
47 |
+ franchiser = FranchiserInfo.objects.get(franchiser_id=chiser) |
|
48 |
+ except FranchiserInfo.DoesNotExist: |
|
49 |
+ return response(FranchiserStatusCode.CHISER_NOT_FOUND) |
|
50 |
+ |
|
51 |
+ fields = { |
|
52 |
+ 'franchiser_id': chiser, |
|
53 |
+ 'franchiser_name': franchiser.franchiser_name, |
|
54 |
+ 'clerk_name': request.POST.get('name', ''), |
|
55 |
+ 'clerk_sex': int(request.POST.get('sex', 1)), |
|
56 |
+ 'clerk_phone': phone, |
|
57 |
+ 'openid': openid, |
|
58 |
+ 'user_status': SaleclerkInfo.UNVERIFIED, |
|
59 |
+ } |
|
60 |
+ |
|
61 |
+ lensman, created = SaleclerkInfo.objects.select_for_update().get_or_create(unionid=unionid, defaults=fields) |
|
62 |
+ # 状态为 UNVERIFIED 的允许修改, 其他需要登录摄影师 APP 进行信息的修改 |
|
63 |
+ if lensman.user_status not in [SaleclerkInfo.UNVERIFIED, SaleclerkInfo.REFUSED]: |
|
64 |
+ return response(SaleclerkInfo.LENSMAN_ALREADY_NOT_UNVERIFIED) |
|
65 |
+ if not created: |
|
66 |
+ for key, value in fields.iteritems(): |
|
67 |
+ setattr(lensman, key, value) |
|
68 |
+ lensman.save() |
|
69 |
+ |
|
70 |
+ return response(200, 'Submit Success', u'提交成功', {}) |
@@ -0,0 +1,111 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from __future__ import division |
|
4 |
+ |
|
5 |
+from django.conf import settings |
|
6 |
+from django.db import transaction |
|
7 |
+from django.shortcuts import render |
|
8 |
+from logit import logit |
|
9 |
+ |
|
10 |
+from account.models import SaleclerkInfo |
|
11 |
+from integral.models import SaleclerkIntegralIncomeExpensesInfo |
|
12 |
+from product.models import ProductCodeSubmitLogInfo, ProductInfo, ProductModelInfo |
|
13 |
+from utils.error.errno_utils import ProductModelStatusCode, ProductStatusCode, SaleclerkStatusCode |
|
14 |
+from utils.error.response_utils import response |
|
15 |
+ |
|
16 |
+ |
|
17 |
+def clerk_sale_oauth(request): |
|
18 |
+ unionid = request.GET.get('unionid', '') |
|
19 |
+ |
|
20 |
+ models = ProductModelInfo.objects.filter(status=True) |
|
21 |
+ models = [model.data for model in models] |
|
22 |
+ |
|
23 |
+ try: |
|
24 |
+ clerk = SaleclerkInfo.objects.get(unionid=unionid) |
|
25 |
+ except SaleclerkInfo.DoesNotExist: |
|
26 |
+ clerk = None |
|
27 |
+ |
|
28 |
+ return render(request, 'page/clerk_sale.html', { |
|
29 |
+ 'domain': settings.DOMAIN, |
|
30 |
+ 'models': models, |
|
31 |
+ 'clerk_info': clerk and clerk.data, |
|
32 |
+ }) |
|
33 |
+ |
|
34 |
+ |
|
35 |
+@logit |
|
36 |
+@transaction.atomic |
|
37 |
+def clerk_sale_submit_api(request): |
|
38 |
+ """ 店员信息提交 """ |
|
39 |
+ clerk_id = request.POST.get('clerk_id', '') |
|
40 |
+ model_id = request.POST.get('model_id', '') |
|
41 |
+ code = request.POST.get('code', '') |
|
42 |
+ name = request.POST.get('name', '') |
|
43 |
+ sex = int(request.POST.get('sex', 1)) |
|
44 |
+ age = int(request.POST.get('age', 1)) |
|
45 |
+ phone = request.POST.get('phone', '') |
|
46 |
+ |
|
47 |
+ # 店员是否存在 |
|
48 |
+ try: |
|
49 |
+ clerk = SaleclerkInfo.objects.select_for_update().get(clerk_id=clerk_id) |
|
50 |
+ except SaleclerkInfo.DoesNotExist: |
|
51 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
52 |
+ |
|
53 |
+ # 店员是否激活 |
|
54 |
+ if clerk.user_status != SaleclerkInfo.ACTIVATED: |
|
55 |
+ return response(SaleclerkStatusCode.CLERK_NOT_ACTIVATED) |
|
56 |
+ |
|
57 |
+ # 型号是否存在 |
|
58 |
+ try: |
|
59 |
+ model = ProductModelInfo.objects.get(model_id=model_id) |
|
60 |
+ except ProductModelInfo.DoesNotExist: |
|
61 |
+ return response(ProductModelStatusCode.MODEL_NOT_FOUND) |
|
62 |
+ |
|
63 |
+ # 记录销售提交记录 |
|
64 |
+ ProductCodeSubmitLogInfo.objects.create( |
|
65 |
+ model_id=model.model_id, |
|
66 |
+ model_name=model.model_name, |
|
67 |
+ code=code, |
|
68 |
+ franchiser_id=clerk.franchiser_id, |
|
69 |
+ clerk_id=clerk.clerk_id, |
|
70 |
+ consumer_name=name, |
|
71 |
+ consumer_sex=sex, |
|
72 |
+ consumer_age=age, |
|
73 |
+ consumer_phone=phone, |
|
74 |
+ ) |
|
75 |
+ |
|
76 |
+ # 产品是否存在 |
|
77 |
+ try: |
|
78 |
+ product = ProductInfo.objects.select_for_update().get(model_id=model_id, code=code) |
|
79 |
+ except ProductInfo.DoesNotExist: |
|
80 |
+ return response(ProductStatusCode.PRODUCT_NOT_FOUND) |
|
81 |
+ |
|
82 |
+ # 产品是否使用 |
|
83 |
+ if product.code_status: |
|
84 |
+ return response(ProductStatusCode.PRODUCT_HAS_USED) |
|
85 |
+ |
|
86 |
+ # 产品使用 |
|
87 |
+ product.code_status = True |
|
88 |
+ product.integral_status = True |
|
89 |
+ product.franchiser_id = clerk.franchiser_id |
|
90 |
+ product.clerk_id = clerk.clerk_id |
|
91 |
+ product.consumer_name = name |
|
92 |
+ product.consumer_sex = sex |
|
93 |
+ product.consumer_age = age |
|
94 |
+ product.consumer_phone = phone |
|
95 |
+ product.save() |
|
96 |
+ |
|
97 |
+ # 店员积分 |
|
98 |
+ clerk.integral += product.integral |
|
99 |
+ clerk.save() |
|
100 |
+ |
|
101 |
+ # 店员积分记录 |
|
102 |
+ SaleclerkIntegralIncomeExpensesInfo.objects.create( |
|
103 |
+ franchiser_id=clerk.franchiser_id, |
|
104 |
+ clerk_id=clerk.clerk_id, |
|
105 |
+ type=SaleclerkIntegralIncomeExpensesInfo.INCOME, |
|
106 |
+ code=code, |
|
107 |
+ integral=product.integral, |
|
108 |
+ left_integral=clerk.integral, |
|
109 |
+ ) |
|
110 |
+ |
|
111 |
+ return response(200, 'Submit Success', u'提交成功', {}) |
@@ -0,0 +1,74 @@ |
||
1 |
+{% load staticfiles %} |
|
2 |
+ |
|
3 |
+<!DOCTYPE html> |
|
4 |
+<html lang="zh-CN"> |
|
5 |
+ <head> |
|
6 |
+ <meta charset="utf-8"> |
|
7 |
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
|
8 |
+ <meta name="format-detection" content="telephone=no,email=no,address=no"> |
|
9 |
+ <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> |
|
10 |
+ <title>店员销售</title> |
|
11 |
+ |
|
12 |
+ <link href="https://res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" /> |
|
13 |
+ |
|
14 |
+ <style> |
|
15 |
+ input:required:invalid { |
|
16 |
+ color: #E64340; |
|
17 |
+ } |
|
18 |
+ input:required:valid { |
|
19 |
+ color: rgb(0, 0, 0); |
|
20 |
+ } |
|
21 |
+ </style> |
|
22 |
+ </head> |
|
23 |
+ <body> |
|
24 |
+ <div class="container" > |
|
25 |
+ <div class="weui_cells_title">基本信息</div> |
|
26 |
+ <div class="weui_cells weui_cells_form"> |
|
27 |
+ <div class="weui_cell"> |
|
28 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div> |
|
29 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
30 |
+ <input id="chiser" class="weui_input" type="text" value="{{ clerk_info.franchiser_name }}" disabled> |
|
31 |
+ </div> |
|
32 |
+ </div> |
|
33 |
+ <div class="weui_cell"> |
|
34 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div> |
|
35 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
36 |
+ <input id="name" class="weui_input" type="text" value="{{ clerk_info.clerk_name }}" disabled> |
|
37 |
+ </div> |
|
38 |
+ </div> |
|
39 |
+ <div class="weui_cell"> |
|
40 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div> |
|
41 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
42 |
+ <input id="sex" class="weui_input" type="text" value="{% ifequal clerk_info.clerk_sex 1 %}男{% else %}女{% endifequal %}" disabled> |
|
43 |
+ </div> |
|
44 |
+ </div> |
|
45 |
+ <div class="weui_cell"> |
|
46 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div> |
|
47 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
48 |
+ <input id="phone" class="weui_input" type="text" required="required" pattern="[0-9]{11}" value="{{ clerk_info.clerk_phone }}" disabled> |
|
49 |
+ </div> |
|
50 |
+ </div> |
|
51 |
+ <div class="weui_cell"> |
|
52 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">积分</label></div> |
|
53 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
54 |
+ <input id="integral" class="weui_input" type="text" required="required" pattern="[0-9]{11}" value="{{ clerk_info.integral }}" disabled> |
|
55 |
+ </div> |
|
56 |
+ </div> |
|
57 |
+ </div> |
|
58 |
+ </div> |
|
59 |
+ |
|
60 |
+ <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> |
|
61 |
+ <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> |
|
62 |
+ <script type="text/javascript" src="{% static 'tamron/js/jswe.js' %}?v=1"></script> |
|
63 |
+ <script> |
|
64 |
+ V.initWxData({ |
|
65 |
+ imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png", |
|
66 |
+ link: 'http://api.pai.ai/wx_oauth2?redirect_url=http://pai.ai/page/lensman&scope=snsapi_base', |
|
67 |
+ desc: "摄影师授权", |
|
68 |
+ title: "摄影师授权", |
|
69 |
+ timeLine: "" |
|
70 |
+ }, true); |
|
71 |
+ V.hideOptionMenu(); |
|
72 |
+ </script> |
|
73 |
+ </body> |
|
74 |
+</html> |
@@ -0,0 +1,198 @@ |
||
1 |
+{% load staticfiles %} |
|
2 |
+ |
|
3 |
+<!DOCTYPE html> |
|
4 |
+<html lang="zh-CN"> |
|
5 |
+ <head> |
|
6 |
+ <meta charset="utf-8"> |
|
7 |
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
|
8 |
+ <meta name="format-detection" content="telephone=no,email=no,address=no"> |
|
9 |
+ <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> |
|
10 |
+ <title>店员授权</title> |
|
11 |
+ |
|
12 |
+ <link href="https://res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" /> |
|
13 |
+ |
|
14 |
+ <style> |
|
15 |
+ input:required:invalid { |
|
16 |
+ color: #E64340; |
|
17 |
+ } |
|
18 |
+ input:required:valid { |
|
19 |
+ color: rgb(0, 0, 0); |
|
20 |
+ } |
|
21 |
+ </style> |
|
22 |
+ </head> |
|
23 |
+ <body> |
|
24 |
+ <div class="container" > |
|
25 |
+ <div class="weui_cells_title">基本信息</div> |
|
26 |
+ <div class="weui_cells weui_cells_form"> |
|
27 |
+ <div class="weui_cell weui_cell_select weui_select_after"> |
|
28 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">经销商</label></div> |
|
29 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
30 |
+ <select id="chiser" class="weui_select" name="select" {% if not modified %}disabled{% endif %}> |
|
31 |
+ {% for chiser in chisers %} |
|
32 |
+ <option value="{{ chiser.franchiser_id }}" {% ifequal chiser.franchiser_id clerk_info.franchiser_id %}selected{% endifequal %}>{{ chiser.franchiser_name }}</option> |
|
33 |
+ {% endfor %} |
|
34 |
+ </select> |
|
35 |
+ </div> |
|
36 |
+ </div> |
|
37 |
+ <div class="weui_cell"> |
|
38 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div> |
|
39 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
40 |
+ <input id="name" class="weui_input" type="text" value="{{ clerk_info.clerk_name }}" placeholder="请输入姓名" {% if not modified %}disabled{% endif %}> |
|
41 |
+ </div> |
|
42 |
+ </div> |
|
43 |
+ <div class="weui_cell weui_cell_select weui_select_after"> |
|
44 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">性别</label></div> |
|
45 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
46 |
+ <select id="sex" class="weui_select" name="select" {% if not modified %}disabled{% endif %}> |
|
47 |
+ <option value="1" {% ifequal clerk_info.clerk_sex 1 %}selected{% endifequal %}>男</option> |
|
48 |
+ <option value="0" {% ifequal clerk_info.clerk_sex 0 %}selected{% endifequal %}>女</option> |
|
49 |
+ </select> |
|
50 |
+ </div> |
|
51 |
+ </div> |
|
52 |
+ <div class="weui_cell"> |
|
53 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div> |
|
54 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
55 |
+ <input id="phone" class="weui_input" type="text" required="required" pattern="[0-9]{11}" value="{{ clerk_info.clerk_phone }}" placeholder="请输入手机号" {% if not modified %}disabled{% endif %}> |
|
56 |
+ </div> |
|
57 |
+ </div> |
|
58 |
+ </div> |
|
59 |
+ |
|
60 |
+ {% if clerk_info %} |
|
61 |
+ <div class="weui_cells_title">审核状态</div> |
|
62 |
+ <div class="weui_cells"> |
|
63 |
+ <div class="weui_cell"> |
|
64 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
65 |
+ <p>状态</p> |
|
66 |
+ </div> |
|
67 |
+ <div class="weui_cell_ft"> |
|
68 |
+ {% ifequal clerk_info.status -1 %}已拒绝{% endifequal %} |
|
69 |
+ {% ifequal clerk_info.status 0 %}审核中{% endifequal %} |
|
70 |
+ {% ifequal clerk_info.status 1 %}已激活{% endifequal %} |
|
71 |
+ {% ifequal clerk_info.status 2 %}已禁用{% endifequal %} |
|
72 |
+ {% ifequal clerk_info.status 3 %}已删除{% endifequal %} |
|
73 |
+ </div> |
|
74 |
+ </div> |
|
75 |
+ </div> |
|
76 |
+ {% endif %} |
|
77 |
+ |
|
78 |
+ |
|
79 |
+ {% ifequal clerk_info.status -1 %} |
|
80 |
+ <div class="weui_cells_title">拒绝原因</div> |
|
81 |
+ <div class="weui_cells"> |
|
82 |
+ <div class="weui_panel_bd"> |
|
83 |
+ <div class="weui_media_box weui_media_text"> |
|
84 |
+ <p class="weui_media_desc">{{ clerk_info.refused_reason|safe|linebreaks }}</p> |
|
85 |
+ </div> |
|
86 |
+ </div> |
|
87 |
+ </div> |
|
88 |
+ {% endifequal %} |
|
89 |
+ |
|
90 |
+ <br> |
|
91 |
+ |
|
92 |
+ {% if modified %}<button id="submit" class="weui_btn weui_btn_warn">确认</button>{% endif %} |
|
93 |
+ |
|
94 |
+ <div class="weui_dialog_alert" id="dialog" style="display: none"> |
|
95 |
+ <div class="weui_mask"></div> |
|
96 |
+ <div class="weui_dialog"> |
|
97 |
+ <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div> |
|
98 |
+ <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div> |
|
99 |
+ <div class="weui_dialog_ft"> |
|
100 |
+ <a href="javascript:;" class="weui_btn_dialog primary">确定</a> |
|
101 |
+ </div> |
|
102 |
+ </div> |
|
103 |
+ </div> |
|
104 |
+ |
|
105 |
+ <div id="toast" style="display: none;"> |
|
106 |
+ <div class="weui_mask_transparent"></div> |
|
107 |
+ <div class="weui_toast"> |
|
108 |
+ <i class="weui_icon_toast"></i> |
|
109 |
+ <p class="weui_toast_content">已完成</p> |
|
110 |
+ </div> |
|
111 |
+ </div> |
|
112 |
+ </div> |
|
113 |
+ |
|
114 |
+ <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> |
|
115 |
+ <script> |
|
116 |
+ {% if modified %} |
|
117 |
+ $(function() { |
|
118 |
+ function getURLParameter(name) { |
|
119 |
+ return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null; |
|
120 |
+ } |
|
121 |
+ |
|
122 |
+ function show_error_dialog(title, content) { |
|
123 |
+ $('#dialog #title').text(title); |
|
124 |
+ $('#dialog #content').text(content); |
|
125 |
+ $('#dialog').show(); |
|
126 |
+ } |
|
127 |
+ |
|
128 |
+ function data_check() { |
|
129 |
+ var unionid = getURLParameter('unionid'); |
|
130 |
+ if (!unionid) { |
|
131 |
+ show_error_dialog('微信授权', '微信授权失败,请重新打开页面'); |
|
132 |
+ return false; |
|
133 |
+ } |
|
134 |
+ |
|
135 |
+ var name = $('#name').val(); |
|
136 |
+ if (!name) { |
|
137 |
+ show_error_dialog('姓名', '姓名错误,请检查重新输入'); |
|
138 |
+ return false; |
|
139 |
+ } |
|
140 |
+ |
|
141 |
+ var phone_valid = $('#phone').is(':valid'); |
|
142 |
+ if (!phone_valid) { |
|
143 |
+ show_error_dialog('手机号', '手机号错误,请检查重新输入'); |
|
144 |
+ return false; |
|
145 |
+ } |
|
146 |
+ |
|
147 |
+ return { |
|
148 |
+ unionid: unionid, |
|
149 |
+ openid: getURLParameter('openid'), |
|
150 |
+ chiser: $('#chiser option:checked').val(), |
|
151 |
+ name: name, |
|
152 |
+ sex: $('#sex option:checked').val(), |
|
153 |
+ phone: $('#phone').val(), |
|
154 |
+ } |
|
155 |
+ } |
|
156 |
+ |
|
157 |
+ $('#submit').click(function () { |
|
158 |
+ var check_result = data_check(); |
|
159 |
+ if (check_result){ |
|
160 |
+ $.ajax({ |
|
161 |
+ type: 'POST', |
|
162 |
+ url: '{{ domain }}api/clerk/submit', |
|
163 |
+ data: check_result, |
|
164 |
+ success: function(data) { |
|
165 |
+ if (data.status == 200) { |
|
166 |
+ $('#toast').show(); |
|
167 |
+ setTimeout(function () { |
|
168 |
+ $('#toast').hide(); |
|
169 |
+ }, 1000); |
|
170 |
+ window.location.reload(); |
|
171 |
+ } else { |
|
172 |
+ show_error_dialog('错误', data.description); |
|
173 |
+ } |
|
174 |
+ } |
|
175 |
+ }) |
|
176 |
+ } |
|
177 |
+ }); |
|
178 |
+ |
|
179 |
+ $('#dialog .weui_btn_dialog').click(function () { |
|
180 |
+ $('#dialog').hide(); |
|
181 |
+ }) |
|
182 |
+ }); |
|
183 |
+ {% endif %} |
|
184 |
+ </script> |
|
185 |
+ <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> |
|
186 |
+ <script type="text/javascript" src="{% static 'tamron/js/jswe.js' %}?v=1"></script> |
|
187 |
+ <script> |
|
188 |
+ V.initWxData({ |
|
189 |
+ imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png", |
|
190 |
+ link: 'http://api.pai.ai/wx_oauth2?redirect_url=http://pai.ai/page/lensman&scope=snsapi_base', |
|
191 |
+ desc: "摄影师授权", |
|
192 |
+ title: "摄影师授权", |
|
193 |
+ timeLine: "" |
|
194 |
+ }, true); |
|
195 |
+ V.hideOptionMenu(); |
|
196 |
+ </script> |
|
197 |
+ </body> |
|
198 |
+</html> |
@@ -0,0 +1,187 @@ |
||
1 |
+{% load staticfiles %} |
|
2 |
+ |
|
3 |
+<!DOCTYPE html> |
|
4 |
+<html lang="zh-CN"> |
|
5 |
+ <head> |
|
6 |
+ <meta charset="utf-8"> |
|
7 |
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
|
8 |
+ <meta name="format-detection" content="telephone=no,email=no,address=no"> |
|
9 |
+ <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> |
|
10 |
+ <title>店员销售</title> |
|
11 |
+ |
|
12 |
+ <link href="https://res.wx.qq.com/open/libs/weui/0.4.3/weui.min.css" rel="stylesheet" type="text/css" /> |
|
13 |
+ |
|
14 |
+ <style> |
|
15 |
+ input:required:invalid { |
|
16 |
+ color: #E64340; |
|
17 |
+ } |
|
18 |
+ input:required:valid { |
|
19 |
+ color: rgb(0, 0, 0); |
|
20 |
+ } |
|
21 |
+ </style> |
|
22 |
+ </head> |
|
23 |
+ <body> |
|
24 |
+ <div class="container" > |
|
25 |
+ <div class="weui_cells_title">机器信息</div> |
|
26 |
+ <div class="weui_cells weui_cells_form"> |
|
27 |
+ <div class="weui_cell weui_cell_select weui_select_after"> |
|
28 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">型号</label></div> |
|
29 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
30 |
+ <select id="model" class="weui_select" name="select"> |
|
31 |
+ {% for model in models %} |
|
32 |
+ <option value="{{ model.model_id }}">{{ model.model_name }}</option> |
|
33 |
+ {% endfor %} |
|
34 |
+ </select> |
|
35 |
+ </div> |
|
36 |
+ </div> |
|
37 |
+ <div class="weui_cell"> |
|
38 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">机身码</label></div> |
|
39 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
40 |
+ <input id="code" class="weui_input" type="text" value="" placeholder="请输入机身码"> |
|
41 |
+ </div> |
|
42 |
+ </div> |
|
43 |
+ </div> |
|
44 |
+ |
|
45 |
+ <div class="weui_cells_title">消费者信息</div> |
|
46 |
+ <div class="weui_cells weui_cells_form"> |
|
47 |
+ <div class="weui_cell"> |
|
48 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">姓名</label></div> |
|
49 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
50 |
+ <input id="name" class="weui_input" type="text" value="" placeholder="请输入消费者姓名"> |
|
51 |
+ </div> |
|
52 |
+ </div> |
|
53 |
+ <div class="weui_cell weui_cell_select weui_select_after"> |
|
54 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">性别</label></div> |
|
55 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
56 |
+ <select id="sex" class="weui_select" name="select"> |
|
57 |
+ <option value="1">男</option> |
|
58 |
+ <option value="0">女</option> |
|
59 |
+ </select> |
|
60 |
+ </div> |
|
61 |
+ </div> |
|
62 |
+ <div class="weui_cell weui_cell_select weui_select_after"> |
|
63 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">年龄</label></div> |
|
64 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
65 |
+ <select id="age" class="weui_select" name="select"> |
|
66 |
+ <option value="1">18周岁以下</option> |
|
67 |
+ <option value="2">60周岁以上</option> |
|
68 |
+ </select> |
|
69 |
+ </div> |
|
70 |
+ </div> |
|
71 |
+ <div class="weui_cell"> |
|
72 |
+ <div class="weui_cell_hd"><label for="" class="weui_label">手机号</label></div> |
|
73 |
+ <div class="weui_cell_bd weui_cell_primary"> |
|
74 |
+ <input id="phone" class="weui_input" type="text" required="required" pattern="[0-9]{11}" value="" placeholder="请输入消费者手机号"> |
|
75 |
+ </div> |
|
76 |
+ </div> |
|
77 |
+ </div> |
|
78 |
+ |
|
79 |
+ <br> |
|
80 |
+ |
|
81 |
+ <button id="submit" class="weui_btn weui_btn_warn">确认</button> |
|
82 |
+ |
|
83 |
+ <div class="weui_dialog_alert" id="dialog" style="display: none"> |
|
84 |
+ <div class="weui_mask"></div> |
|
85 |
+ <div class="weui_dialog"> |
|
86 |
+ <div class="weui_dialog_hd"><strong id="title" class="weui_dialog_title">弹窗标题</strong></div> |
|
87 |
+ <div id="content" class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div> |
|
88 |
+ <div class="weui_dialog_ft"> |
|
89 |
+ <a href="javascript:;" class="weui_btn_dialog primary">确定</a> |
|
90 |
+ </div> |
|
91 |
+ </div> |
|
92 |
+ </div> |
|
93 |
+ |
|
94 |
+ <div id="toast" style="display: none;"> |
|
95 |
+ <div class="weui_mask_transparent"></div> |
|
96 |
+ <div class="weui_toast"> |
|
97 |
+ <i class="weui_icon_toast"></i> |
|
98 |
+ <p class="weui_toast_content">已完成</p> |
|
99 |
+ </div> |
|
100 |
+ </div> |
|
101 |
+ </div> |
|
102 |
+ |
|
103 |
+ <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> |
|
104 |
+ <script> |
|
105 |
+ $(function() { |
|
106 |
+ function show_error_dialog(title, content) { |
|
107 |
+ $('#dialog #title').text(title); |
|
108 |
+ $('#dialog #content').text(content); |
|
109 |
+ $('#dialog').show(); |
|
110 |
+ } |
|
111 |
+ |
|
112 |
+ function data_check() { |
|
113 |
+ var clerk_id = "{{ clerk_info.clerk_id }}"; |
|
114 |
+ if (!clerk_id) { |
|
115 |
+ show_error_dialog('微信授权', '微信授权失败,请重新打开页面'); |
|
116 |
+ return false; |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ var code = $('#code').val(); |
|
120 |
+ if (!code) { |
|
121 |
+ show_error_dialog('机身码', '机身码错误,请检查重新输入'); |
|
122 |
+ return false; |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ var name = $('#name').val(); |
|
126 |
+ if (!name) { |
|
127 |
+ show_error_dialog('姓名', '姓名错误,请检查重新输入'); |
|
128 |
+ return false; |
|
129 |
+ } |
|
130 |
+ |
|
131 |
+ var phone_valid = $('#phone').is(':valid'); |
|
132 |
+ if (!phone_valid) { |
|
133 |
+ show_error_dialog('手机号', '手机号错误,请检查重新输入'); |
|
134 |
+ return false; |
|
135 |
+ } |
|
136 |
+ |
|
137 |
+ return { |
|
138 |
+ clerk_id: clerk_id, |
|
139 |
+ model_id: $('#model option:checked').val(), |
|
140 |
+ code: code, |
|
141 |
+ name: name, |
|
142 |
+ sex: $('#sex option:checked').val(), |
|
143 |
+ age: $('#age option:checked').val(), |
|
144 |
+ phone: $('#phone').val(), |
|
145 |
+ } |
|
146 |
+ } |
|
147 |
+ |
|
148 |
+ $('#submit').click(function () { |
|
149 |
+ var check_result = data_check(); |
|
150 |
+ if (check_result){ |
|
151 |
+ $.ajax({ |
|
152 |
+ type: 'POST', |
|
153 |
+ url: '{{ domain }}api/clerk/sale/submit', |
|
154 |
+ data: check_result, |
|
155 |
+ success: function(data) { |
|
156 |
+ if (data.status == 200) { |
|
157 |
+ $('#toast').show(); |
|
158 |
+ setTimeout(function () { |
|
159 |
+ $('#toast').hide(); |
|
160 |
+ }, 1000); |
|
161 |
+ } else { |
|
162 |
+ show_error_dialog('错误', data.description); |
|
163 |
+ } |
|
164 |
+ } |
|
165 |
+ }) |
|
166 |
+ } |
|
167 |
+ }); |
|
168 |
+ |
|
169 |
+ $('#dialog .weui_btn_dialog').click(function () { |
|
170 |
+ $('#dialog').hide(); |
|
171 |
+ }) |
|
172 |
+ }); |
|
173 |
+ </script> |
|
174 |
+ <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> |
|
175 |
+ <script type="text/javascript" src="{% static 'tamron/js/jswe.js' %}?v=1"></script> |
|
176 |
+ <script> |
|
177 |
+ V.initWxData({ |
|
178 |
+ imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png", |
|
179 |
+ link: 'http://api.pai.ai/wx_oauth2?redirect_url=http://pai.ai/page/lensman&scope=snsapi_base', |
|
180 |
+ desc: "摄影师授权", |
|
181 |
+ title: "摄影师授权", |
|
182 |
+ timeLine: "" |
|
183 |
+ }, true); |
|
184 |
+ V.hideOptionMenu(); |
|
185 |
+ </script> |
|
186 |
+ </body> |
|
187 |
+</html> |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.test import TestCase |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your tests here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.shortcuts import render |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your views here. |
@@ -0,0 +1,9 @@ |
||
1 |
+#!/bin/bash |
|
2 |
+ |
|
3 |
+# Ignoring autogenerated files |
|
4 |
+# -- Migration directories |
|
5 |
+# Ignoring error codes |
|
6 |
+# -- E128 continuation line under-indented for visual indent |
|
7 |
+# -- E501 line too long |
|
8 |
+ |
|
9 |
+pep8 --exclude=migrations --ignore=E128,E501 . |
@@ -0,0 +1,29 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.contrib import admin |
|
4 |
+ |
|
5 |
+from product.models import ProductCodeSubmitLogInfo, ProductInfo, ProductModelInfo |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class ProductModelInfoAdmin(admin.ModelAdmin): |
|
9 |
+ readonly_fields = ('model_id', ) |
|
10 |
+ list_display = ('model_id', 'model_name', 'integral', 'status', 'created_at', 'updated_at') |
|
11 |
+ search_fields = ('model_id', 'model_name') |
|
12 |
+ list_filter = ('status', ) |
|
13 |
+ |
|
14 |
+ |
|
15 |
+class ProductInfoAdmin(admin.ModelAdmin): |
|
16 |
+ list_display = ('model_id', 'model_name', 'code', 'code_status', 'integral', 'integral_status', 'franchiser_id', 'clerk_id', 'consumer_name', 'consumer_sex', 'consumer_age', 'consumer_phone', 'status', 'created_at', 'updated_at') |
|
17 |
+ search_fields = ('model_id', 'model_name', 'code', 'consumer_name', 'consumer_phone') |
|
18 |
+ list_filter = ('code_status', 'integral_status', 'franchiser_id', 'consumer_sex', 'status') |
|
19 |
+ |
|
20 |
+ |
|
21 |
+class ProductCodeSubmitLogInfoAdmin(admin.ModelAdmin): |
|
22 |
+ list_display = ('model_id', 'model_name', 'code', 'franchiser_id', 'clerk_id', 'consumer_name', 'consumer_sex', 'consumer_age', 'consumer_phone', 'status', 'created_at', 'updated_at') |
|
23 |
+ search_fields = ('model_id', 'model_name', 'code', 'consumer_name', 'consumer_phone') |
|
24 |
+ list_filter = ('franchiser_id', 'consumer_sex', 'status') |
|
25 |
+ |
|
26 |
+ |
|
27 |
+admin.site.register(ProductModelInfo, ProductModelInfoAdmin) |
|
28 |
+admin.site.register(ProductInfo, ProductInfoAdmin) |
|
29 |
+admin.site.register(ProductCodeSubmitLogInfo, ProductCodeSubmitLogInfoAdmin) |
@@ -0,0 +1,77 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+import shortuuidfield.fields |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.CreateModel( |
|
15 |
+ name='ProductCodeSubmitLogInfo', |
|
16 |
+ fields=[ |
|
17 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
18 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
19 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
20 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
21 |
+ ('model_id', models.CharField(max_length=255, blank=True, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='model_id', db_index=True)), |
|
22 |
+ ('model_name', models.CharField(max_length=255, blank=True, help_text='\u578b\u53f7\u540d\u79f0', null=True, verbose_name='model_name', db_index=True)), |
|
23 |
+ ('code', models.CharField(help_text='\u673a\u8eab\u7801', max_length=255, null=True, verbose_name='code', blank=True)), |
|
24 |
+ ('franchiser_id', models.CharField(max_length=255, blank=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='franchiser_id', db_index=True)), |
|
25 |
+ ('clerk_id', models.CharField(max_length=255, blank=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='clerk_id', db_index=True)), |
|
26 |
+ ('consumer_name', models.CharField(help_text='\u6d88\u8d39\u8005\u540d\u79f0', max_length=255, null=True, verbose_name='consumer_name', blank=True)), |
|
27 |
+ ('consumer_sex', models.IntegerField(default=1, help_text='\u6d88\u8d39\u8005\u6027\u522b', db_index=True, verbose_name='consumer_sex', choices=[(1, '\u7537'), (0, '\u5973')])), |
|
28 |
+ ('consumer_age', models.IntegerField(default=0, help_text='\u6d88\u8d39\u8005\u5e74\u9f84', verbose_name='consumer_age')), |
|
29 |
+ ('consumer_phone', models.CharField(help_text='\u6d88\u8d39\u8005\u8054\u7cfb\u7535\u8bdd', max_length=255, null=True, verbose_name='consumer_phone', blank=True)), |
|
30 |
+ ], |
|
31 |
+ options={ |
|
32 |
+ 'verbose_name': 'productcodesubmitloginfo', |
|
33 |
+ 'verbose_name_plural': 'productcodesubmitloginfo', |
|
34 |
+ }, |
|
35 |
+ ), |
|
36 |
+ migrations.CreateModel( |
|
37 |
+ name='ProductInfo', |
|
38 |
+ fields=[ |
|
39 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
40 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
41 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
42 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
43 |
+ ('model_id', models.CharField(max_length=255, blank=True, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='model_id', db_index=True)), |
|
44 |
+ ('model_name', models.CharField(max_length=255, blank=True, help_text='\u578b\u53f7\u540d\u79f0', null=True, verbose_name='model_name', db_index=True)), |
|
45 |
+ ('code', models.CharField(help_text='\u673a\u8eab\u7801', max_length=255, null=True, verbose_name='code', blank=True)), |
|
46 |
+ ('code_status', models.BooleanField(default=False, help_text='\u673a\u8eab\u7801\u72b6\u6001', db_index=True, verbose_name='code_status')), |
|
47 |
+ ('integral', models.IntegerField(default=0, help_text='\u79ef\u5206', verbose_name='integral')), |
|
48 |
+ ('integral_status', models.BooleanField(default=False, help_text='\u79ef\u5206\u72b6\u6001', db_index=True, verbose_name='integral_status')), |
|
49 |
+ ('franchiser_id', models.CharField(max_length=255, blank=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='franchiser_id', db_index=True)), |
|
50 |
+ ('clerk_id', models.CharField(max_length=255, blank=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='clerk_id', db_index=True)), |
|
51 |
+ ('consumer_name', models.CharField(help_text='\u6d88\u8d39\u8005\u540d\u79f0', max_length=255, null=True, verbose_name='consumer_name', blank=True)), |
|
52 |
+ ('consumer_sex', models.IntegerField(default=1, help_text='\u6d88\u8d39\u8005\u6027\u522b', db_index=True, verbose_name='consumer_sex', choices=[(1, '\u7537'), (0, '\u5973')])), |
|
53 |
+ ('consumer_age', models.IntegerField(default=0, help_text='\u6d88\u8d39\u8005\u5e74\u9f84', verbose_name='consumer_age')), |
|
54 |
+ ('consumer_phone', models.CharField(help_text='\u6d88\u8d39\u8005\u8054\u7cfb\u7535\u8bdd', max_length=255, null=True, verbose_name='consumer_phone', blank=True)), |
|
55 |
+ ], |
|
56 |
+ options={ |
|
57 |
+ 'verbose_name': 'productinfo', |
|
58 |
+ 'verbose_name_plural': 'productinfo', |
|
59 |
+ }, |
|
60 |
+ ), |
|
61 |
+ migrations.CreateModel( |
|
62 |
+ name='ProductModelInfo', |
|
63 |
+ fields=[ |
|
64 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
65 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
66 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
67 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
68 |
+ ('model_id', shortuuidfield.fields.ShortUUIDField(editable=False, max_length=22, blank=True, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', unique=True, db_index=True)), |
|
69 |
+ ('model_name', models.CharField(help_text='\u578b\u53f7\u540d\u79f0', max_length=255, null=True, verbose_name='model_name', blank=True)), |
|
70 |
+ ('integral', models.IntegerField(default=0, help_text='\u578b\u53f7\u79ef\u5206', verbose_name='integral')), |
|
71 |
+ ], |
|
72 |
+ options={ |
|
73 |
+ 'verbose_name': '\u4ea7\u54c1\u578b\u53f7\u4fe1\u606f', |
|
74 |
+ 'verbose_name_plural': '\u4ea7\u54c1\u578b\u53f7\u4fe1\u606f', |
|
75 |
+ }, |
|
76 |
+ ), |
|
77 |
+ ] |
@@ -0,0 +1,24 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('product', '0001_initial'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.AlterField( |
|
15 |
+ model_name='productinfo', |
|
16 |
+ name='code_status', |
|
17 |
+ field=models.BooleanField(default=False, help_text='\u673a\u8eab\u7801\u72b6\u6001, True\u5df2\u4f7f\u7528\uff0cFalse\u672a\u4f7f\u7528', db_index=True, verbose_name='code_status'), |
|
18 |
+ ), |
|
19 |
+ migrations.AlterField( |
|
20 |
+ model_name='productinfo', |
|
21 |
+ name='integral_status', |
|
22 |
+ field=models.BooleanField(default=False, help_text='\u79ef\u5206\u72b6\u6001, True\u5df2\u79ef\u5206\uff0cFalse\u672a\u79ef\u5206', db_index=True, verbose_name='integral_status'), |
|
23 |
+ ), |
|
24 |
+ ] |
@@ -0,0 +1,99 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.db import models |
|
4 |
+from django.utils.translation import ugettext_lazy as _ |
|
5 |
+from shortuuidfield import ShortUUIDField |
|
6 |
+ |
|
7 |
+from tamron.basemodels import CreateUpdateMixin |
|
8 |
+ |
|
9 |
+ |
|
10 |
+class ProductModelInfo(CreateUpdateMixin): |
|
11 |
+ model_id = ShortUUIDField(_(u'model_id'), max_length=255, help_text=u'型号唯一标识', db_index=True, unique=True) |
|
12 |
+ model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称') |
|
13 |
+ integral = models.IntegerField(_(u'integral'), default=0, help_text=u'型号积分') |
|
14 |
+ |
|
15 |
+ class Meta: |
|
16 |
+ verbose_name = _(u'产品型号信息') |
|
17 |
+ verbose_name_plural = _(u'产品型号信息') |
|
18 |
+ |
|
19 |
+ def __unicode__(self): |
|
20 |
+ return unicode(self.pk) |
|
21 |
+ |
|
22 |
+ @property |
|
23 |
+ def data(self): |
|
24 |
+ return { |
|
25 |
+ 'model_id': self.model_id, |
|
26 |
+ 'model_name': self.model_name, |
|
27 |
+ 'integral': self.integral, |
|
28 |
+ } |
|
29 |
+ |
|
30 |
+ |
|
31 |
+class ProductInfo(CreateUpdateMixin): |
|
32 |
+ MALE = 1 |
|
33 |
+ FEMALE = 0 |
|
34 |
+ |
|
35 |
+ SEX_TYPE = ( |
|
36 |
+ (MALE, u'男'), |
|
37 |
+ (FEMALE, u'女'), |
|
38 |
+ ) |
|
39 |
+ |
|
40 |
+ model_id = models.CharField(_(u'model_id'), max_length=255, blank=True, null=True, help_text=u'型号唯一标识', db_index=True) |
|
41 |
+ model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称', db_index=True) |
|
42 |
+ |
|
43 |
+ code = models.CharField(_(u'code'), max_length=255, blank=True, null=True, help_text=u'机身码') |
|
44 |
+ code_status = models.BooleanField(_(u'code_status'), default=False, help_text=u'机身码状态, True已使用,False未使用', db_index=True) |
|
45 |
+ |
|
46 |
+ integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分') |
|
47 |
+ integral_status = models.BooleanField(_(u'integral_status'), default=False, help_text=u'积分状态, True已积分,False未积分', db_index=True) |
|
48 |
+ |
|
49 |
+ franchiser_id = models.CharField(_(u'franchiser_id'), max_length=255, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) |
|
50 |
+ clerk_id = models.CharField(_(u'clerk_id'), max_length=255, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) |
|
51 |
+ |
|
52 |
+ consumer_name = models.CharField(_(u'consumer_name'), max_length=255, blank=True, null=True, help_text=u'消费者名称') |
|
53 |
+ consumer_sex = models.IntegerField(_(u'consumer_sex'), choices=SEX_TYPE, default=MALE, help_text=u'消费者性别', db_index=True) |
|
54 |
+ consumer_age = models.IntegerField(_(u'consumer_age'), default=0, help_text=u'消费者年龄') |
|
55 |
+ consumer_phone = models.CharField(_(u'consumer_phone'), max_length=255, blank=True, null=True, help_text=u'消费者联系电话') |
|
56 |
+ |
|
57 |
+ class Meta: |
|
58 |
+ verbose_name = _(u'productinfo') |
|
59 |
+ verbose_name_plural = _(u'productinfo') |
|
60 |
+ |
|
61 |
+ def __unicode__(self): |
|
62 |
+ return unicode(self.pk) |
|
63 |
+ |
|
64 |
+ @property |
|
65 |
+ def data(self): |
|
66 |
+ return { |
|
67 |
+ 'model_id': self.model_id, |
|
68 |
+ 'model_name': self.model_name, |
|
69 |
+ 'code': self.code, |
|
70 |
+ } |
|
71 |
+ |
|
72 |
+ |
|
73 |
+class ProductCodeSubmitLogInfo(CreateUpdateMixin): |
|
74 |
+ MALE = 1 |
|
75 |
+ FEMALE = 0 |
|
76 |
+ |
|
77 |
+ SEX_TYPE = ( |
|
78 |
+ (MALE, u'男'), |
|
79 |
+ (FEMALE, u'女'), |
|
80 |
+ ) |
|
81 |
+ |
|
82 |
+ model_id = models.CharField(_(u'model_id'), max_length=255, blank=True, null=True, help_text=u'型号唯一标识', db_index=True) |
|
83 |
+ model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称', db_index=True) |
|
84 |
+ code = models.CharField(_(u'code'), max_length=255, blank=True, null=True, help_text=u'机身码') |
|
85 |
+ |
|
86 |
+ franchiser_id = models.CharField(_(u'franchiser_id'), max_length=255, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) |
|
87 |
+ clerk_id = models.CharField(_(u'clerk_id'), max_length=255, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) |
|
88 |
+ |
|
89 |
+ consumer_name = models.CharField(_(u'consumer_name'), max_length=255, blank=True, null=True, help_text=u'消费者名称') |
|
90 |
+ consumer_sex = models.IntegerField(_(u'consumer_sex'), choices=SEX_TYPE, default=MALE, help_text=u'消费者性别', db_index=True) |
|
91 |
+ consumer_age = models.IntegerField(_(u'consumer_age'), default=0, help_text=u'消费者年龄') |
|
92 |
+ consumer_phone = models.CharField(_(u'consumer_phone'), max_length=255, blank=True, null=True, help_text=u'消费者联系电话') |
|
93 |
+ |
|
94 |
+ class Meta: |
|
95 |
+ verbose_name = _(u'productcodesubmitloginfo') |
|
96 |
+ verbose_name_plural = _(u'productcodesubmitloginfo') |
|
97 |
+ |
|
98 |
+ def __unicode__(self): |
|
99 |
+ return unicode(self.pk) |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.test import TestCase |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your tests here. |
@@ -0,0 +1,4 @@ |
||
1 |
+from django.shortcuts import render |
|
2 |
+ |
|
3 |
+ |
|
4 |
+# Create your views here. |
@@ -0,0 +1,39 @@ |
||
1 |
+-e git+https://github.com/Brightcells/django-q.git#egg=django-q |
|
2 |
+-e git+https://github.com/andymccurdy/redis-py.git#egg=redis-py |
|
3 |
+CodeConvert==2.0.4 |
|
4 |
+Django==1.8.4 |
|
5 |
+MySQL-python==1.2.5 |
|
6 |
+Pillow==3.4.2 |
|
7 |
+StatusCode==1.0.0 |
|
8 |
+TimeConvert==1.4.1 |
|
9 |
+cryptography==1.5.2 |
|
10 |
+django-curtail-uuid==1.0.0 |
|
11 |
+django-detect==1.0.5 |
|
12 |
+django-file-md5==1.0.1 |
|
13 |
+django-ip==1.0.0 |
|
14 |
+django-json-response==1.1.4 |
|
15 |
+django-logit==1.0.6 |
|
16 |
+django-multidomain==1.1.4 |
|
17 |
+django-paginator2==1.0.3 |
|
18 |
+django-rlog==1.0.7 |
|
19 |
+django-shortuuidfield==0.1.3 |
|
20 |
+django-six==1.0.2 |
|
21 |
+djangorestframework==3.6.3 |
|
22 |
+furl==1.0.0 |
|
23 |
+hiredis==0.2.0 |
|
24 |
+isoweek==1.3.3 |
|
25 |
+jsonfield==2.0.2 |
|
26 |
+mock==2.0.0 |
|
27 |
+pep8==1.7.0 |
|
28 |
+pysnippets==1.0.4 |
|
29 |
+pywe-miniapp==1.0.0 |
|
30 |
+pywe-oauth==1.0.3 |
|
31 |
+pywe-response==1.0.1 |
|
32 |
+qiniu==7.1.4 |
|
33 |
+redis-extensions==1.0.50 |
|
34 |
+requests==2.12.4 |
|
35 |
+rlog==0.2 |
|
36 |
+shortuuid==0.5.0 |
|
37 |
+uWSGI==2.0.15 |
|
38 |
+versions==0.10.0 |
|
39 |
+wechatpy==1.2.8 |
@@ -0,0 +1,13 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.db import models |
|
4 |
+from django.utils.translation import ugettext_lazy as _ |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class CreateUpdateMixin(models.Model): |
|
8 |
+ status = models.BooleanField(_(u'status'), default=True, help_text=_(u'状态'), db_index=True) |
|
9 |
+ created_at = models.DateTimeField(_(u'created_at'), auto_now_add=True, editable=True, help_text=_(u'创建时间')) |
|
10 |
+ updated_at = models.DateTimeField(_(u'updated_at'), auto_now=True, editable=True, help_text=_(u'更新时间')) |
|
11 |
+ |
|
12 |
+ class Meta: |
|
13 |
+ abstract = True |
@@ -0,0 +1,16 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+import redis_extensions as redis |
|
4 |
+ |
|
5 |
+ |
|
6 |
+def redis_conf(conf): |
|
7 |
+ return { |
|
8 |
+ 'host': conf.get('HOST', 'localhost'), |
|
9 |
+ 'port': conf.get('PORT', 6379), |
|
10 |
+ 'password': '{}:{}'.format(conf.get('USER', ''), conf.get('PASSWORD', '')) if conf.get('USER') else '', |
|
11 |
+ 'db': conf.get('db', 0), |
|
12 |
+ } |
|
13 |
+ |
|
14 |
+ |
|
15 |
+def redis_connect(conf): |
|
16 |
+ return redis.StrictRedisExtensions(connection_pool=redis.ConnectionPool(**redis_conf(conf))) |
@@ -0,0 +1,29 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+import os |
|
4 |
+ |
|
5 |
+ |
|
6 |
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
|
7 |
+PROJ_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) |
|
8 |
+ |
|
9 |
+TEMPLATES = [ |
|
10 |
+ { |
|
11 |
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates', |
|
12 |
+ 'DIRS': [os.path.join(BASE_DIR, 'templates')], |
|
13 |
+ # 'APP_DIRS': True, |
|
14 |
+ 'OPTIONS': { |
|
15 |
+ 'context_processors': [ |
|
16 |
+ 'django.template.context_processors.debug', |
|
17 |
+ 'django.template.context_processors.request', |
|
18 |
+ 'django.contrib.auth.context_processors.auth', |
|
19 |
+ 'django.contrib.messages.context_processors.messages', |
|
20 |
+ ], |
|
21 |
+ 'loaders': [ |
|
22 |
+ 'django.template.loaders.filesystem.Loader', |
|
23 |
+ 'django.template.loaders.app_directories.Loader', |
|
24 |
+ ], |
|
25 |
+ }, |
|
26 |
+ }, |
|
27 |
+] |
|
28 |
+ |
|
29 |
+DOMAIN = 'http://127.0.0.1:9997/' |
@@ -0,0 +1,254 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+""" |
|
4 |
+Django settings for tamron project. |
|
5 |
+ |
|
6 |
+Generated by 'django-admin startproject' using Django 1.8.4. |
|
7 |
+ |
|
8 |
+For more information on this file, see |
|
9 |
+https://docs.djangoproject.com/en/1.8/topics/settings/ |
|
10 |
+ |
|
11 |
+For the full list of settings and their values, see |
|
12 |
+https://docs.djangoproject.com/en/1.8/ref/settings/ |
|
13 |
+""" |
|
14 |
+ |
|
15 |
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...) |
|
16 |
+import os |
|
17 |
+ |
|
18 |
+ |
|
19 |
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
|
20 |
+PROJ_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) |
|
21 |
+ |
|
22 |
+ |
|
23 |
+# Quick-start development settings - unsuitable for production |
|
24 |
+# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ |
|
25 |
+ |
|
26 |
+# SECURITY WARNING: keep the secret key used in production secret! |
|
27 |
+SECRET_KEY = '@!_8xi9(8)gj8zvni#)2-arn)4gn^u&coy-0yld0=1r5*ao@4i' |
|
28 |
+ |
|
29 |
+# SECURITY WARNING: don't run with debug turned on in production! |
|
30 |
+DEBUG = True |
|
31 |
+ |
|
32 |
+ALLOWED_HOSTS = [] |
|
33 |
+ |
|
34 |
+ |
|
35 |
+# Application definition |
|
36 |
+ |
|
37 |
+INSTALLED_APPS = ( |
|
38 |
+ 'django.contrib.admin', |
|
39 |
+ 'django.contrib.auth', |
|
40 |
+ 'django.contrib.contenttypes', |
|
41 |
+ 'django.contrib.sessions', |
|
42 |
+ 'django.contrib.messages', |
|
43 |
+ 'django.contrib.staticfiles', |
|
44 |
+ 'api', |
|
45 |
+ 'account', |
|
46 |
+ 'integral', |
|
47 |
+ 'page', |
|
48 |
+ 'product', |
|
49 |
+) |
|
50 |
+ |
|
51 |
+MIDDLEWARE_CLASSES = ( |
|
52 |
+ 'django.contrib.sessions.middleware.SessionMiddleware', |
|
53 |
+ 'django.middleware.common.CommonMiddleware', |
|
54 |
+ # 'django.middleware.csrf.CsrfViewMiddleware', |
|
55 |
+ 'django.contrib.auth.middleware.AuthenticationMiddleware', |
|
56 |
+ 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', |
|
57 |
+ 'django.contrib.messages.middleware.MessageMiddleware', |
|
58 |
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware', |
|
59 |
+ 'django.middleware.security.SecurityMiddleware', |
|
60 |
+) |
|
61 |
+ |
|
62 |
+ROOT_URLCONF = 'tamron.urls' |
|
63 |
+ |
|
64 |
+TEMPLATES = [ |
|
65 |
+ { |
|
66 |
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates', |
|
67 |
+ 'DIRS': [os.path.join(BASE_DIR, 'templates')], |
|
68 |
+ # 'APP_DIRS': True, |
|
69 |
+ 'OPTIONS': { |
|
70 |
+ 'context_processors': [ |
|
71 |
+ 'django.template.context_processors.debug', |
|
72 |
+ 'django.template.context_processors.request', |
|
73 |
+ 'django.contrib.auth.context_processors.auth', |
|
74 |
+ 'django.contrib.messages.context_processors.messages', |
|
75 |
+ ], |
|
76 |
+ 'loaders': [ |
|
77 |
+ ('django.template.loaders.cached.Loader', [ |
|
78 |
+ 'django.template.loaders.filesystem.Loader', |
|
79 |
+ 'django.template.loaders.app_directories.Loader', |
|
80 |
+ ]), |
|
81 |
+ ], |
|
82 |
+ }, |
|
83 |
+ }, |
|
84 |
+] |
|
85 |
+ |
|
86 |
+WSGI_APPLICATION = 'tamron.wsgi.application' |
|
87 |
+ |
|
88 |
+ |
|
89 |
+# Database |
|
90 |
+# https://docs.djangoproject.com/en/1.8/ref/settings/#databases |
|
91 |
+ |
|
92 |
+DATABASES = { |
|
93 |
+ 'default': { |
|
94 |
+ 'ENGINE': 'django.db.backends.mysql', |
|
95 |
+ 'NAME': 'tamron', |
|
96 |
+ 'USER': 'root', |
|
97 |
+ 'PASSWORD': '', |
|
98 |
+ 'CONN_MAX_AGE': 600, |
|
99 |
+ 'OPTIONS': { |
|
100 |
+ # Utf8mb4 for Emoji |
|
101 |
+ # |
|
102 |
+ # Nickname |
|
103 |
+ # |
|
104 |
+ # account.WechatInfo ==> nickname |
|
105 |
+ # ALTER TABLE account_wechatinfo MODIFY COLUMN nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; |
|
106 |
+ # account.UserInfo ==> nickname |
|
107 |
+ # ALTER TABLE account_userinfo MODIFY COLUMN nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; |
|
108 |
+ # group.GroupUserInfo ==> nickname |
|
109 |
+ # ALTER TABLE group_groupuserinfo MODIFY COLUMN nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL; |
|
110 |
+ # group.GroupPhotoInfo ==> nickname |
|
111 |
+ # ALTER TABLE group_groupphotoinfo MODIFY COLUMN nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL; |
|
112 |
+ # group.PhotoCommentInfo ==> nickname |
|
113 |
+ # ALTER TABLE group_photocommentinfo MODIFY COLUMN nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL; |
|
114 |
+ # group.PhotoThumbUpInfo ==> nickname |
|
115 |
+ # ALTER TABLE group_photothumbupinfo MODIFY COLUMN nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL; |
|
116 |
+ # group.UserMessageInfo ==> nickname |
|
117 |
+ # ALTER TABLE message_usermessageinfo MODIFY COLUMN from_nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL; |
|
118 |
+ # |
|
119 |
+ # Comment |
|
120 |
+ # group.PhotoCommentInfo ==> comment |
|
121 |
+ # ALTER TABLE group_photocommentinfo MODIFY COLUMN comment LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; |
|
122 |
+ 'charset': 'utf8mb4', |
|
123 |
+ }, |
|
124 |
+ } |
|
125 |
+} |
|
126 |
+ |
|
127 |
+ |
|
128 |
+# Internationalization |
|
129 |
+# https://docs.djangoproject.com/en/1.8/topics/i18n/ |
|
130 |
+ |
|
131 |
+LANGUAGE_CODE = 'zh-Hans' |
|
132 |
+ |
|
133 |
+TIME_ZONE = 'Asia/Shanghai' |
|
134 |
+ |
|
135 |
+USE_I18N = True |
|
136 |
+ |
|
137 |
+USE_L10N = True |
|
138 |
+ |
|
139 |
+USE_TZ = True |
|
140 |
+ |
|
141 |
+ |
|
142 |
+# Static files (CSS, JavaScript, Images) |
|
143 |
+# https://docs.djangoproject.com/en/1.8/howto/static-files/ |
|
144 |
+ |
|
145 |
+STATICFILES_DIRS = ( |
|
146 |
+ os.path.join(PROJ_DIR, 'static').replace('\\', '/'), |
|
147 |
+) |
|
148 |
+ |
|
149 |
+STATIC_ROOT = os.path.join(BASE_DIR, 'collect_static').replace('\\', '/') |
|
150 |
+ |
|
151 |
+STATIC_URL = '/static/' |
|
152 |
+ |
|
153 |
+STATICFILES_FINDERS = ( |
|
154 |
+ 'django.contrib.staticfiles.finders.FileSystemFinder', |
|
155 |
+ 'django.contrib.staticfiles.finders.AppDirectoriesFinder', |
|
156 |
+ # 'django.contrib.staticfiles.finders.DefaultStorageFinder', |
|
157 |
+) |
|
158 |
+ |
|
159 |
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/') |
|
160 |
+ |
|
161 |
+MEDIA_URL = '/media/' |
|
162 |
+ |
|
163 |
+# Redis 设置 |
|
164 |
+REDIS = { |
|
165 |
+ 'default': { |
|
166 |
+ 'HOST': '127.0.0.1', |
|
167 |
+ 'PORT': 6379, |
|
168 |
+ 'USER': '', |
|
169 |
+ 'PASSWORD': '', |
|
170 |
+ 'db': 0, |
|
171 |
+ } |
|
172 |
+} |
|
173 |
+ |
|
174 |
+# 微信设置 |
|
175 |
+WECHAT = { |
|
176 |
+ 'JSAPI': { |
|
177 |
+ 'token': '5201314', |
|
178 |
+ 'appID': '', |
|
179 |
+ 'appsecret': '', |
|
180 |
+ 'mchID': '', |
|
181 |
+ 'apiKey': '', |
|
182 |
+ 'mch_cert': '', |
|
183 |
+ 'mch_key': '', |
|
184 |
+ 'redpacket': { |
|
185 |
+ |
|
186 |
+ } |
|
187 |
+ }, |
|
188 |
+} |
|
189 |
+ |
|
190 |
+# 微信授权设置 |
|
191 |
+WECHAT_BASE_REDIRECT_URI = 'https://api.pai.ai/base_redirect' |
|
192 |
+WECHAT_USERINFO_REDIRECT_URI = 'https://api.pai.ai/userinfo_redirect' |
|
193 |
+WECHAT_OAUTH2_RETRY_REDIRECT_URI = 'https://api.pai.ai/wx_oauth2?redirect_url={}' |
|
194 |
+ |
|
195 |
+WECHAT_OAUTH2_REDIRECT_URL = 'https://api.pai.ai/wx_oauth2?redirect_url={}' |
|
196 |
+ |
|
197 |
+# LOGIT 设置 |
|
198 |
+LOGIT_BODY_FLAG = True |
|
199 |
+LOGIT_RES_FLAG = True |
|
200 |
+ |
|
201 |
+DOMAIN = '' |
|
202 |
+ |
|
203 |
+try: |
|
204 |
+ from local_settings import * |
|
205 |
+except ImportError: |
|
206 |
+ pass |
|
207 |
+ |
|
208 |
+try: |
|
209 |
+ from func_settings import redis_connect |
|
210 |
+ REDIS_CACHE = redis_connect(REDIS.get('default', {})) |
|
211 |
+ |
|
212 |
+ DJLOGIT = { |
|
213 |
+ 'level': 'DEBUG', |
|
214 |
+ 'class': 'rlog.RedisListHandler', |
|
215 |
+ 'redis_client': REDIS_CACHE, |
|
216 |
+ 'key': 'django:logit:tamron', |
|
217 |
+ 'formatter': 'verbose', |
|
218 |
+ } |
|
219 |
+except ImportError: |
|
220 |
+ REDIS_CACHE = None |
|
221 |
+ |
|
222 |
+# 日志设置 |
|
223 |
+LOGGING = { |
|
224 |
+ 'version': 1, |
|
225 |
+ 'disable_existing_loggers': False, |
|
226 |
+ 'formatters': { |
|
227 |
+ 'verbose': { |
|
228 |
+ 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' |
|
229 |
+ }, |
|
230 |
+ 'simple': { |
|
231 |
+ 'format': '%(levelname)s %(message)s' |
|
232 |
+ }, |
|
233 |
+ }, |
|
234 |
+ 'handlers': { |
|
235 |
+ 'logit': DJLOGIT, |
|
236 |
+ 'console': { |
|
237 |
+ 'level': 'DEBUG', |
|
238 |
+ 'class': 'logging.StreamHandler', |
|
239 |
+ 'formatter': 'verbose' |
|
240 |
+ }, |
|
241 |
+ }, |
|
242 |
+ 'loggers': { |
|
243 |
+ 'logit': { |
|
244 |
+ 'handlers': ['logit'], |
|
245 |
+ 'level': 'DEBUG', |
|
246 |
+ 'propagate': True, |
|
247 |
+ }, |
|
248 |
+ 'console': { |
|
249 |
+ 'handlers': ['console'], |
|
250 |
+ 'level': 'DEBUG', |
|
251 |
+ 'propagate': True, |
|
252 |
+ }, |
|
253 |
+ }, |
|
254 |
+} |
@@ -0,0 +1,300 @@ |
||
1 |
+!(function(e, t) { |
|
2 |
+ var config = { |
|
3 |
+ wxconfig: 'http://api.pai.ai/wx/jsapi_signature', |
|
4 |
+ callback: 'callback' |
|
5 |
+ }, wxData = { |
|
6 |
+ debug: false, |
|
7 |
+ imgUrl: '', |
|
8 |
+ link: '', |
|
9 |
+ desc: '', |
|
10 |
+ title: '', |
|
11 |
+ timeLine: '' |
|
12 |
+ }, wxConfig = { |
|
13 |
+ hide: false, |
|
14 |
+ close: false |
|
15 |
+ }, jsApiList = [ |
|
16 |
+ 'checkJsApi', |
|
17 |
+ 'onMenuShareTimeline', |
|
18 |
+ 'onMenuShareAppMessage', |
|
19 |
+ 'onMenuShareQQ', |
|
20 |
+ 'onMenuShareWeibo', |
|
21 |
+ 'hideMenuItems', |
|
22 |
+ 'showMenuItems', |
|
23 |
+ 'hideAllNonBaseMenuItem', |
|
24 |
+ 'showAllNonBaseMenuItem', |
|
25 |
+ 'translateVoice', |
|
26 |
+ 'startRecord', |
|
27 |
+ 'stopRecord', |
|
28 |
+ 'onRecordEnd', |
|
29 |
+ 'playVoice', |
|
30 |
+ 'pauseVoice', |
|
31 |
+ 'stopVoice', |
|
32 |
+ 'uploadVoice', |
|
33 |
+ 'downloadVoice', |
|
34 |
+ 'chooseImage', |
|
35 |
+ 'previewImage', |
|
36 |
+ 'uploadImage', |
|
37 |
+ 'downloadImage', |
|
38 |
+ 'getNetworkType', |
|
39 |
+ 'openLocation', |
|
40 |
+ 'getLocation', |
|
41 |
+ 'hideOptionMenu', |
|
42 |
+ 'showOptionMenu', |
|
43 |
+ 'closeWindow', |
|
44 |
+ 'scanQRCode', |
|
45 |
+ 'chooseWXPay', |
|
46 |
+ 'openEnterpriseRedPacket', |
|
47 |
+ 'openProductSpecificView', |
|
48 |
+ 'addCard', |
|
49 |
+ 'chooseCard', |
|
50 |
+ 'openCard' |
|
51 |
+ ], wxApiFun |
|
52 |
+ |
|
53 |
+ function isOpenOnPC() { // 判断当前网页是否在 PC 浏览器中打开 |
|
54 |
+ var ua = navigator.userAgent |
|
55 |
+ return /windows nt/i.test(ua) || /macintosh/i.test(ua) || /linux x86_64/i.test(ua) |
|
56 |
+ } |
|
57 |
+ |
|
58 |
+ function isOpenInWeixin() { // 判断当前网页是否在微信内置浏览器中打开 |
|
59 |
+ return /micromessenger/i.test(navigator.userAgent) |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ function getWeixinVersion() { |
|
63 |
+ var ua = navigator.userAgent, |
|
64 |
+ mt = ua.match(/micromessenger\/([\d.]+)/i) |
|
65 |
+ return (mt ? mt[1] : '') |
|
66 |
+ } |
|
67 |
+ |
|
68 |
+ // This function checks whether Wechat is the appointed version or not |
|
69 |
+ // Cmp: http://jsperf.com/regexp-test-vs-indexof-ignore-upper-and-lower |
|
70 |
+ function isWeixinVersion(version) { |
|
71 |
+ // return new RegExp('micromessenger/' + version , 'i').test(navigator.userAgent) |
|
72 |
+ return navigator.userAgent.toLowerCase().indexOf('micromessenger/' + version) != -1 |
|
73 |
+ } |
|
74 |
+ |
|
75 |
+ function hideOptionMenu() { |
|
76 |
+ wxConfig.hide = true |
|
77 |
+ fixedWxData() |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ function showOptionMenu() { |
|
81 |
+ wxConfig.hide = false |
|
82 |
+ fixedWxData() |
|
83 |
+ } |
|
84 |
+ |
|
85 |
+ function closeWindow() { |
|
86 |
+ wxConfig.close = true |
|
87 |
+ fixedWxData() |
|
88 |
+ } |
|
89 |
+ |
|
90 |
+ function wxReady(data) { |
|
91 |
+ data = typeof data === 'object' ? data : JSON.parse(data) |
|
92 |
+ wx.config({ |
|
93 |
+ debug: wxData.debug, |
|
94 |
+ appId: data.appId, |
|
95 |
+ timestamp: data.timestamp, |
|
96 |
+ nonceStr: data.nonceStr, |
|
97 |
+ signature: data.signature, |
|
98 |
+ jsApiList: jsApiList |
|
99 |
+ }) |
|
100 |
+ |
|
101 |
+ var callbacks = { |
|
102 |
+ trigger: function (res) { |
|
103 |
+ // alert('用户点击发送给朋友') |
|
104 |
+ if (JSWE.wxTrigger) {JSWE.wxTrigger(res)} |
|
105 |
+ }, |
|
106 |
+ success: function (res) { |
|
107 |
+ // alert('已分享') |
|
108 |
+ if (JSWE.wxSuccess) {JSWE.wxSuccess(res)} |
|
109 |
+ }, |
|
110 |
+ cancel: function (res) { |
|
111 |
+ // alert('已取消') |
|
112 |
+ if (JSWE.wxCancel) {JSWE.wxCancel(res)} |
|
113 |
+ }, |
|
114 |
+ fail: function (res) { |
|
115 |
+ // alert(JSON.stringify(res)) |
|
116 |
+ if (JSWE.wxFail) {JSWE.wxFail(res)} |
|
117 |
+ } |
|
118 |
+ }, shareInfo = function(flag) { |
|
119 |
+ var _share = { |
|
120 |
+ title: flag ? wxData.title : (wxData.timeLine || wxData.desc), |
|
121 |
+ link: wxData.link, |
|
122 |
+ imgUrl: wxData.imgUrl, |
|
123 |
+ trigger: callbacks.trigger, |
|
124 |
+ success: callbacks.success, |
|
125 |
+ cancel: callbacks.cancel, |
|
126 |
+ fail: callbacks.fail |
|
127 |
+ } |
|
128 |
+ if (flag) _share.desc = wxData.desc |
|
129 |
+ return _share |
|
130 |
+ }, wxShareApi = function() { |
|
131 |
+ // 2. 分享接口 |
|
132 |
+ // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口 |
|
133 |
+ wx.onMenuShareAppMessage(shareInfo(1)) |
|
134 |
+ // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口 |
|
135 |
+ wx.onMenuShareTimeline(shareInfo(0)) |
|
136 |
+ // 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口 |
|
137 |
+ wx.onMenuShareQQ(shareInfo(1)) |
|
138 |
+ // 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口 |
|
139 |
+ wx.onMenuShareWeibo(shareInfo(1)) |
|
140 |
+ }, wxMenuApi = function () { |
|
141 |
+ // 8. 界面操作接口 |
|
142 |
+ // 8.1 隐藏右上角菜单 |
|
143 |
+ // 8.2 显示右上角菜单 |
|
144 |
+ if (wxConfig.hide) {wx.hideOptionMenu()} else {wx.showOptionMenu()} |
|
145 |
+ // 8.7 关闭当前窗口 |
|
146 |
+ if (wxConfig.close) {wx.closeWindow()} |
|
147 |
+ }, wxApi = function () { |
|
148 |
+ wxShareApi() |
|
149 |
+ wxMenuApi() |
|
150 |
+ } |
|
151 |
+ |
|
152 |
+ wx.ready(wxApi) |
|
153 |
+ |
|
154 |
+ return wxApiFun = wxApi |
|
155 |
+ } |
|
156 |
+ |
|
157 |
+ if (isOpenInWeixin() || isOpenOnPC()) { |
|
158 |
+ if ('undefined' !== typeof JSWE_CONF_UPDATE) JSWE_CONF_UPDATE(config) |
|
159 |
+ $.ajax({ |
|
160 |
+ url: config.wxconfig, |
|
161 |
+ type: 'get', |
|
162 |
+ dataType: 'jsonp', |
|
163 |
+ jsonpCallback: config.callback, |
|
164 |
+ data: { |
|
165 |
+ url: window.location.href.split('#')[0] |
|
166 |
+ }, |
|
167 |
+ success: wxReady |
|
168 |
+ }) |
|
169 |
+ } |
|
170 |
+ |
|
171 |
+ function initWxData(data, flag) { |
|
172 |
+ for(var d in data) {if (d in wxData) wxData[d] = data[d]} |
|
173 |
+ if (flag) fixedWxData() |
|
174 |
+ } |
|
175 |
+ |
|
176 |
+ function changeWxData(key, value, flag) { |
|
177 |
+ if (key in falDwxDataata) {wxData[key] = value} |
|
178 |
+ if (flag) fixedWxData() |
|
179 |
+ } |
|
180 |
+ |
|
181 |
+ function fixedWxData() { |
|
182 |
+ if ('undefined' !== typeof wxApiFun) wxApiFun() |
|
183 |
+ } |
|
184 |
+ |
|
185 |
+ // 5 图片接口 |
|
186 |
+ // 5.1 拍照、本地选图 |
|
187 |
+ var images = { |
|
188 |
+ localIds: [], |
|
189 |
+ serverIds: [] |
|
190 |
+ }; |
|
191 |
+ function chooseImage(count, directUpload, isShowProgressTips) { |
|
192 |
+ if ('undefined' === typeof count) {count = 9} |
|
193 |
+ if ('undefined' === typeof directUpload) {directUpload = false} |
|
194 |
+ if ('undefined' === typeof isShowProgressTips) {isShowProgressTips = 1} |
|
195 |
+ wx.chooseImage({ |
|
196 |
+ count: count, // 默认9 |
|
197 |
+ sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 |
|
198 |
+ sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 |
|
199 |
+ success: function (res) { |
|
200 |
+ var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 |
|
201 |
+ images.localIds = localIds; |
|
202 |
+ // 判断是否直接上传 |
|
203 |
+ if (directUpload) {setTimeout(uploadImages(localIds, isShowProgressTips), 100)} |
|
204 |
+ // 拍照、本地选图成功后的回调函数 |
|
205 |
+ if (JSWE.wxChooseImageSuccess) {JSWE.wxChooseImageSuccess(res)} |
|
206 |
+ } |
|
207 |
+ }); |
|
208 |
+ } |
|
209 |
+ |
|
210 |
+ // 5.3 上传图片 |
|
211 |
+ function uploadImage(localId, isShowProgressTips) { |
|
212 |
+ // 上传图片为异步处理,重复上传同一图片,返回的serverId也是不同的 |
|
213 |
+ wx.uploadImage({ |
|
214 |
+ localId: localId, // 需要上传的图片的本地ID,由chooseImage接口获得 |
|
215 |
+ isShowProgressTips: 1, // 默认为1,显示进度提示 |
|
216 |
+ success: function (res) { |
|
217 |
+ var serverId = res.serverId; // 返回图片的服务器端ID |
|
218 |
+ images.serverIds.push(serverId); |
|
219 |
+ // 上传图片成功后的回调函数 |
|
220 |
+ if (JSWE.wxUploadImageSuccess) {JSWE.wxUploadImageSuccess(res)} |
|
221 |
+ } |
|
222 |
+ }); |
|
223 |
+ } |
|
224 |
+ |
|
225 |
+ function uploadImages(localIds, isShowProgressTips) { |
|
226 |
+ if ('undefined' === typeof localIds) {localIds = images.localIds} |
|
227 |
+ if ('undefined' === typeof isShowProgressTips) {isShowProgressTips = 1} |
|
228 |
+ images.serverIds = []; |
|
229 |
+ for (var index in localIds) {uploadImage(localIds[index], isShowProgressTips)} |
|
230 |
+ } |
|
231 |
+ |
|
232 |
+ // 10 微信支付接口 |
|
233 |
+ // 10.1 发起一个支付请求 |
|
234 |
+ function chooseWXPay(wxpay_params) { |
|
235 |
+ wx.chooseWXPay({ |
|
236 |
+ timestamp: wxpay_params.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 |
|
237 |
+ nonceStr: wxpay_params.nonceStr, // 支付签名随机串,不长于 32 位 |
|
238 |
+ package: wxpay_params.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) |
|
239 |
+ signType: wxpay_params.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' |
|
240 |
+ paySign: wxpay_params.paySign, // 支付签名 |
|
241 |
+ success: function (res) { |
|
242 |
+ // 支付成功后的回调函数 |
|
243 |
+ if (JSWE.wxPaySuccess) {JSWE.wxPaySuccess(res)} |
|
244 |
+ } |
|
245 |
+ }) |
|
246 |
+ } |
|
247 |
+ |
|
248 |
+ // xx 微信原生企业红包接口 |
|
249 |
+ // xx.1 发起一个发送原生企业红包请求 |
|
250 |
+ function openEnterpriseRedPacket(wxredpack_params) { |
|
251 |
+ wx.openEnterpriseRedPacket({ |
|
252 |
+ timeStamp: wxredpack_params.timeStamp, // 红包签名时间戳,注意原生企业红包接口timeStamp字段名需大写其中的S字符,而支付接口timeStamp字段名无需大写其中的S字符。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 |
|
253 |
+ nonceStr: wxredpack_params.nonceStr, // 红包签名随机串,不长于 32 位 |
|
254 |
+ package: encodeURIComponent(wxredpack_params.package), // 发放红包接口返回的prepay_id参数值,提交格式如:prepay_id=***) |
|
255 |
+ signType: wxredpack_params.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' |
|
256 |
+ paySign: wxredpack_params.paySign, // 红包签名 |
|
257 |
+ success: function (res) { |
|
258 |
+ // 发送原生企业红包成功后的回调函数 |
|
259 |
+ if (JSWE.wxEnterpriseRedPacketSuccess) {JSWE.wxEnterpriseRedPacketSuccess(res)} |
|
260 |
+ } |
|
261 |
+ }) |
|
262 |
+ } |
|
263 |
+ |
|
264 |
+ var v = { |
|
265 |
+ version: '1.0.5', |
|
266 |
+ |
|
267 |
+ // Basic Vars |
|
268 |
+ config: config, |
|
269 |
+ wxData: wxData, |
|
270 |
+ jsApiList: jsApiList, |
|
271 |
+ |
|
272 |
+ // Weixin Function |
|
273 |
+ isOpenInWeixin: isOpenInWeixin, |
|
274 |
+ getWeixinVersion: getWeixinVersion, |
|
275 |
+ isWeixinVersion: isWeixinVersion, |
|
276 |
+ |
|
277 |
+ // Menu Function |
|
278 |
+ hideOptionMenu: hideOptionMenu, |
|
279 |
+ showOptionMenu: showOptionMenu, |
|
280 |
+ closeWindow: closeWindow, |
|
281 |
+ |
|
282 |
+ // Share Function |
|
283 |
+ initWxData: initWxData, |
|
284 |
+ changeWxData: changeWxData, |
|
285 |
+ fixedWxData: fixedWxData, |
|
286 |
+ |
|
287 |
+ // Image Function |
|
288 |
+ images: images, |
|
289 |
+ chooseImage: chooseImage, |
|
290 |
+ uploadImage: uploadImage, |
|
291 |
+ uploadImages: uploadImages, |
|
292 |
+ |
|
293 |
+ // Pay Function |
|
294 |
+ chooseWXPay: chooseWXPay, |
|
295 |
+ |
|
296 |
+ // EnterpriseRedPacket Function |
|
297 |
+ openEnterpriseRedPacket: openEnterpriseRedPacket |
|
298 |
+ } |
|
299 |
+ e.JSWE = e.V = v |
|
300 |
+})(window) |
@@ -0,0 +1,33 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+"""tamron URL Configuration |
|
4 |
+ |
|
5 |
+The `urlpatterns` list routes URLs to views. For more information please see: |
|
6 |
+ https://docs.djangoproject.com/en/1.8/topics/http/urls/ |
|
7 |
+Examples: |
|
8 |
+Function views |
|
9 |
+ 1. Add an import: from my_app import views |
|
10 |
+ 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') |
|
11 |
+Class-based views |
|
12 |
+ 1. Add an import: from other_app.views import Home |
|
13 |
+ 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') |
|
14 |
+Including another URLconf |
|
15 |
+ 1. Add an import: from blog import urls as blog_urls |
|
16 |
+ 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) |
|
17 |
+""" |
|
18 |
+from django.conf.urls import include, url |
|
19 |
+from django.contrib import admin |
|
20 |
+ |
|
21 |
+from page import info_views, oauth_views, sale_views |
|
22 |
+ |
|
23 |
+ |
|
24 |
+urlpatterns = [ |
|
25 |
+ url(r'^admin/', include(admin.site.urls)), |
|
26 |
+ url(r'^api/', include('api.urls', namespace='api')), |
|
27 |
+] |
|
28 |
+ |
|
29 |
+urlpatterns += [ |
|
30 |
+ url(r'^page/clerk$', oauth_views.clerk_oauth, name='clerk_oauth'), # 店员授权页面 |
|
31 |
+ url(r'^page/clerk/sale$', sale_views.clerk_sale_oauth, name='clerk_sale_oauth'), # 店员销售授权页面 |
|
32 |
+ url(r'^page/clerk/info$', info_views.clerk_info_oauth, name='clerk_info_oauth'), # 店员信息授权页面 |
|
33 |
+] |
@@ -0,0 +1,2 @@ |
||
1 |
+killall -9 uwsgi |
|
2 |
+echo "2敏加油~~~!!!↖(^ω^)↗" |
@@ -0,0 +1,2 @@ |
||
1 |
+nohup uwsgi --ini pai2.ini &>pai2.log & |
|
2 |
+echo "Start Success !!!" |
@@ -0,0 +1,27 @@ |
||
1 |
+# tamron_uwsgi.ini file |
|
2 |
+[uwsgi] |
|
3 |
+ |
|
4 |
+# Django-related settings |
|
5 |
+# the base directory (full path) |
|
6 |
+chdir = /home/paiai/work/tamron |
|
7 |
+# Django's wsgi file |
|
8 |
+module = tamron.wsgi |
|
9 |
+# the virtualenv (full path) |
|
10 |
+# home = /path/to/virtualenv |
|
11 |
+ |
|
12 |
+# process-related settings |
|
13 |
+# master |
|
14 |
+master = true |
|
15 |
+# maximum number of worker processes |
|
16 |
+processes = 10 |
|
17 |
+# the socket (use the full path to be safe |
|
18 |
+socket = /home/paiai/work/tamron/tamron/uwsgi/tamron.sock |
|
19 |
+# ... with appropriate permissions - may be needed |
|
20 |
+chmod-socket = 777 |
|
21 |
+# clear environment on exit |
|
22 |
+vacuum = true |
|
23 |
+ |
|
24 |
+# 11: Resource temporarily unavailable |
|
25 |
+reload-mercy = 64 |
|
26 |
+max-requests = 8192 |
|
27 |
+listen = 4096 |
@@ -0,0 +1,35 @@ |
||
1 |
+# tamron_nginx.conf |
|
2 |
+ |
|
3 |
+# the upstream component nginx needs to connect to |
|
4 |
+upstream pai2 { |
|
5 |
+ # server unix:///home/paiai/work/tamron/tamron/uwsgi/tamron.sock; # for a file socket |
|
6 |
+ server 127.0.0.1:8888; # for a web port socket (we'll use this first) |
|
7 |
+} |
|
8 |
+ |
|
9 |
+# configuration of the server |
|
10 |
+server { |
|
11 |
+ # the port your site will be served on |
|
12 |
+ listen 80; |
|
13 |
+ # the domain name it will serve for |
|
14 |
+ server_name .tamron.xfoto.com.cn; # substitute your machine's IP address or FQDN |
|
15 |
+ charset utf-8; |
|
16 |
+ |
|
17 |
+ # max upload size |
|
18 |
+ client_max_body_size 75M; # adjust to taste |
|
19 |
+ |
|
20 |
+ # Django media |
|
21 |
+ location /media { |
|
22 |
+ alias /home/paiai/work/tamron/media; # your Django project's media files - amend as required |
|
23 |
+ } |
|
24 |
+ |
|
25 |
+ location /static { |
|
26 |
+ alias /home/paiai/work/tamron/collect_static; # your Django project's static files - amend as required |
|
27 |
+ } |
|
28 |
+ |
|
29 |
+ # Finally, send all non-media requests to the Django server. |
|
30 |
+ location / { |
|
31 |
+ # uwsgi_pass tamron; |
|
32 |
+ proxy_pass http://tamron; |
|
33 |
+ include /home/paiai/work/tamron/tamron/uwsgi/uwsgi_params; # the uwsgi_params file you installed |
|
34 |
+ } |
|
35 |
+} |
@@ -0,0 +1,15 @@ |
||
1 |
+uwsgi_param QUERY_STRING $query_string; |
|
2 |
+uwsgi_param REQUEST_METHOD $request_method; |
|
3 |
+uwsgi_param CONTENT_TYPE $content_type; |
|
4 |
+uwsgi_param CONTENT_LENGTH $content_length; |
|
5 |
+ |
|
6 |
+uwsgi_param REQUEST_URI $request_uri; |
|
7 |
+uwsgi_param PATH_INFO $document_uri; |
|
8 |
+uwsgi_param DOCUMENT_ROOT $document_root; |
|
9 |
+uwsgi_param SERVER_PROTOCOL $server_protocol; |
|
10 |
+uwsgi_param UWSGI_SCHEME $scheme; |
|
11 |
+ |
|
12 |
+uwsgi_param REMOTE_ADDR $remote_addr; |
|
13 |
+uwsgi_param REMOTE_PORT $remote_port; |
|
14 |
+uwsgi_param SERVER_PORT $server_port; |
|
15 |
+uwsgi_param SERVER_NAME $server_name; |
@@ -0,0 +1,17 @@ |
||
1 |
+""" |
|
2 |
+WSGI config for tamron project. |
|
3 |
+ |
|
4 |
+It exposes the WSGI callable as a module-level variable named ``application``. |
|
5 |
+ |
|
6 |
+For more information on this file, see |
|
7 |
+https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ |
|
8 |
+""" |
|
9 |
+ |
|
10 |
+import os |
|
11 |
+ |
|
12 |
+from django.core.wsgi import get_wsgi_application |
|
13 |
+ |
|
14 |
+ |
|
15 |
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tamron.settings") |
|
16 |
+ |
|
17 |
+application = get_wsgi_application() |
@@ -0,0 +1,62 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from StatusCode import BaseStatusCode, StatusCodeField |
|
4 |
+ |
|
5 |
+ |
|
6 |
+class FranchiserStatusCode(BaseStatusCode): |
|
7 |
+ """ 店员相关错误码 4001xx """ |
|
8 |
+ CHISER_NOT_FOUND = StatusCodeField(400001, 'Chiser Not Found', description=u'经销商不存在') |
|
9 |
+ |
|
10 |
+ |
|
11 |
+class SaleclerkStatusCode(BaseStatusCode): |
|
12 |
+ """ 店员相关错误码 4001xx """ |
|
13 |
+ CLERK_NOT_FOUND = StatusCodeField(400101, 'Clerk Not Found', description=u'店员不存在') |
|
14 |
+ # 手机号 |
|
15 |
+ CLERK_PHONE_ALREADY_EXISTS = StatusCodeField(400105, 'Clerk Phone Already Exists', description=u'手机号已经存在') |
|
16 |
+ # 状态 |
|
17 |
+ CLERK_ALREADY_NOT_UNVERIFIED = StatusCodeField(400110, 'Clerk Already Not Unverified', description=u'店员帐号已激活') |
|
18 |
+ CLERK_NOT_ACTIVATED = StatusCodeField(400115, 'Clerk Not Activated', description=u'店员帐号未激活') |
|
19 |
+ |
|
20 |
+ |
|
21 |
+class ProductModelStatusCode(BaseStatusCode): |
|
22 |
+ """ 型号相关错误码 4010xx """ |
|
23 |
+ MODEL_NOT_FOUND = StatusCodeField(401001, 'Model Not Found', description=u'型号不存在') |
|
24 |
+ |
|
25 |
+ |
|
26 |
+class ProductStatusCode(BaseStatusCode): |
|
27 |
+ """ 产品相关错误码 4020xx """ |
|
28 |
+ PRODUCT_NOT_FOUND = StatusCodeField(402001, 'Product Not Found', description=u'产品不存在') |
|
29 |
+ # 状态 |
|
30 |
+ PRODUCT_HAS_USED = StatusCodeField(402011, 'Product Has Used', description=u'产品已使用') |
|
31 |
+ |
|
32 |
+ |
|
33 |
+class OrderStatusCode(BaseStatusCode): |
|
34 |
+ """ 订单/支付相关错误码 4040xx """ |
|
35 |
+ WX_UNIFIED_ORDER_FAIL = StatusCodeField(404000, 'WX Unified Order Fail', description=u'微信统一下单失败') |
|
36 |
+ WX_ORDER_NOT_FOUND = StatusCodeField(404001, 'WX Order Not Found', description=u'订单不存在') |
|
37 |
+ WX_ORDER_NOT_PAY = StatusCodeField(404002, 'WX Order Not Pay', description=u'订单未支付') |
|
38 |
+ WX_ORDER_PAYING = StatusCodeField(404003, 'WX Order Paying', description=u'订单支付中') |
|
39 |
+ WX_ORDER_PAY_FAIL = StatusCodeField(404009, 'WX Order Pay Fail', description=u'微信支付失败') |
|
40 |
+ SIGN_CHECK_FAIL = StatusCodeField(404010, 'Sign Check Fail', description=u'签名校验失败') |
|
41 |
+ FEE_CHECK_FAIL = StatusCodeField(404011, 'FEE Check Fail', description=u'金额校验失败') |
|
42 |
+ NO_DETAIL_PERMISSION = StatusCodeField(404015, 'No Detail Permission', description=u'无详情权限') |
|
43 |
+ WX_ORDER_PAID_ALREADY_EXISTS = StatusCodeField(404020, 'WX Order Paid Already Exists', description=u'照片已购买') |
|
44 |
+ |
|
45 |
+ |
|
46 |
+class PayStatusCode(BaseStatusCode): |
|
47 |
+ """ 支付相关错误码 4041xx """ |
|
48 |
+ |
|
49 |
+ |
|
50 |
+class WithdrawStatusCode(BaseStatusCode): |
|
51 |
+ """ 提现相关错误码 4042xx """ |
|
52 |
+ BALANCE_NOT_ENOUGH = StatusCodeField(404200, 'Balance Not Enough', description=u'提现金额不足') |
|
53 |
+ |
|
54 |
+ |
|
55 |
+class MessageStatusCode(BaseStatusCode): |
|
56 |
+ """ 消息相关错误码 4090xx """ |
|
57 |
+ MESSAGE_NOT_FOUND = StatusCodeField(409001, 'Message Not Found', description=u'消息不存在') |
|
58 |
+ |
|
59 |
+ |
|
60 |
+class TokenStatusCode(BaseStatusCode): |
|
61 |
+ """ 票据相关错误码 4090xx """ |
|
62 |
+ TOKEN_NOT_FOUND = StatusCodeField(409901, 'Token Not Found', description=u'票据不存在') |
@@ -0,0 +1,18 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.http import JsonResponse |
|
4 |
+from StatusCode import StatusCodeField |
|
5 |
+ |
|
6 |
+ |
|
7 |
+def response_data(status_code=200, message=None, description=None, data={}, **kwargs): |
|
8 |
+ return dict({ |
|
9 |
+ 'status': status_code, |
|
10 |
+ 'message': message, |
|
11 |
+ 'description': description, |
|
12 |
+ 'data': data, |
|
13 |
+ }, **kwargs) |
|
14 |
+ |
|
15 |
+ |
|
16 |
+def response(status_code=200, message=None, description=None, data={}, **kwargs): |
|
17 |
+ message, description = (message or status_code.message, description or status_code.description) if isinstance(status_code, StatusCodeField) else (message, description) |
|
18 |
+ return JsonResponse(response_data(status_code, message, description, data, **kwargs), safe=False) |
@@ -0,0 +1,6 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.conf import settings |
|
4 |
+ |
|
5 |
+ |
|
6 |
+r = settings.REDIS_CACHE |
@@ -0,0 +1,68 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+# 唯一标识相关 |
|
4 |
+UUID_LIST = 'uuid:list' # List,唯一标识列表 |
|
5 |
+ |
|
6 |
+# 用户相关 |
|
7 |
+PROFILE_INFO = 'profile:info:%s' # STRING,用户信息,user_id |
|
8 |
+ |
|
9 |
+# 导游相关 |
|
10 |
+TOUR_GUIDE_GROUP_GEO_INFO = 'tour:guide:group:geo:info:%s' # ZSET,旅游团地理位置信息,group_id |
|
11 |
+TOUR_GUIDE_GROUP_GEO_SUBMIT_DT = 'tour:guide:group:geo:submit:dt:%s' # ZSET,旅游团地理位置最后上传时间,group_id |
|
12 |
+TOUR_GUIDE_GROUP_CUR_SESSION = 'tour:guide:group:cur:session:%s' # STRING,旅游团当前Session,group_id,导游设置集合时间的时候更新 |
|
13 |
+TOUR_GUIDE_GROUP_CUR_GATHER_INFO = 'tour:guide:group:cur:gather:info:%s' # STRING,旅游团当前Session,group_id,导游设置集合时间的时候更新 |
|
14 |
+TOUR_GUIDE_GROUP_USER_GEO_LIST = 'tour:guide:group:user:geo:list:%s:%s:%s' # LIST,旅游团当前用户地理位置列表,group_id、session_id、user_id |
|
15 |
+ |
|
16 |
+TOUR_GUIDE_GROUP_USER_OWN = 'tour:guide:group:user:own:%s' # STRING,导游当前拥有的旅行团,user_id,导游创建旅行团的时候更新 |
|
17 |
+TOUR_GUIDE_GROUP_USER_BELONG = 'tour:guide:group:user:belong:%s' # STRING,用户当前所属旅行团,user_id,用户加入旅行团的时候更新 |
|
18 |
+ |
|
19 |
+# 群组相关 |
|
20 |
+GROUP_INFO = 'group:info:%s' # STRING,群组信息,group_id |
|
21 |
+ |
|
22 |
+# 群组用户相关 |
|
23 |
+GROUP_USERS_INFO = 'group:users:info:%s' # STRING,群组用户信息,group_id |
|
24 |
+GROUP_USERS_KV_INFO = 'group:users:kv:info:%s' # STRING,群组用户信息,group_id |
|
25 |
+GROUP_USERS_APPLYING_SET = 'group:users:applying:set:%s' # SET,群组用户申请集合,group_id |
|
26 |
+GROUP_USERS_PASSED_SET = 'group:users:passed:set:%s' # SET,群组用户通过集合,group_id |
|
27 |
+GROUP_USERS_REFUSED_SET = 'group:users:refused:set:%s' # SET,群组用户拒绝集合,group_id |
|
28 |
+GROUP_USERS_DELETED_SET = 'group:users:deleted:set:%s' # SET,群组用户移除集合,group_id |
|
29 |
+GROUP_USERS_QUIT_SET = 'group:users:quit:set:%s' # SET,群组用户退出集合,group_id |
|
30 |
+ |
|
31 |
+# 群组照片相关 |
|
32 |
+GROUP_PHOTO_DATA = 'group:photo:data:%s' # STRING,群组数据记录,group_id |
|
33 |
+GROUP_PHOTO_THUMB_UP = 'group:photo:thumb:up:%s:%s' # STRING,群组照片用户点赞记录,photo_id、user_id |
|
34 |
+GROUP_PHOTO_COMMENT_LIST = 'group:photo:comment:list:%s' # STRING,群组照片用户评论列表,photo_id |
|
35 |
+GROUP_PHOTO_THUMB_UP_LIST = 'group:photo:thumb:up:list:%s' # STRING,群组照片用户点赞列表,photo_id |
|
36 |
+GROUP_PHOTO_WATCHER_SET = 'group:photo:watcher:set:%s' # SET,群组照片用户关注集合,photo_id,关注即评论点赞 |
|
37 |
+GROUP_LAST_PHOTO_PK = 'group:last:photo:pk:%s' # STRING,群组最后一张照片PK,group_id |
|
38 |
+ |
|
39 |
+# 摄影师照片相关 |
|
40 |
+LENSMAN_PHOTO_ORDER_RECORD = 'lensman:photo:order:record:%s:%s' # STRING,摄影师照片购买记录,photo_id、user_id |
|
41 |
+ |
|
42 |
+# 摄影师简报相关 |
|
43 |
+# 收入 |
|
44 |
+TOTAL_INCOME = 'total:income:%s:%s' # STRING,总收入,user_id、photo_type |
|
45 |
+WEEK_INCOME = 'week:income:%s:%s:%s' # STRING,周收入,user_id、photo_type、Week.thisweek().isoformat() |
|
46 |
+TODAY_INCOME = 'today:income:%s:%s:%s' # STRING,日收入,user_id、photo_type、tc.local_string(format='%Y%m%d') |
|
47 |
+# 上传 |
|
48 |
+TODAY_UPLOAD_PHOTO_AMOUNT = 'today:upload:photo:amount:%s:%s' # STRING,日上传照片数量,user_id、tc.local_string(format='%Y%m%d') |
|
49 |
+# 售出 |
|
50 |
+WEEK_SOLD = 'week:sold:%s:%s:%s' # STRING,周售出,user_id、photo_type、Week.thisweek().isoformat() |
|
51 |
+ |
|
52 |
+# 摄影师定价相关 |
|
53 |
+LENSMAN_PHOTO_PRICE_FIXED = 'lensman:photo:price:fixed:%s' # STRING,摄影师照片定价(单位:分),user_id |
|
54 |
+ |
|
55 |
+# 系统消息相关 |
|
56 |
+SYSTEM_MESSAGE_READ_INFO = 'system:message:read:info:%s' # STRING,系统消息读取信息,user_id |
|
57 |
+SYSTEM_MESSAGE_DELETED_INFO = 'system:message:deleted:info:%s' # STRING,系统消息删除信息,user_id |
|
58 |
+ |
|
59 |
+# 游客入口相关 |
|
60 |
+GUEST_ENTRANCE_CONTROL_INFO = 'guest:entrance:control:info:%s' # STRING,游客入口控制信息,src |
|
61 |
+ |
|
62 |
+# APP 相关 |
|
63 |
+LATEST_APP_INFO = 'latest:app:info:%s' # STRING,最新 APP 信息,src |
|
64 |
+APP_SETTINGS_INFO = 'app:settings:info:%s:%s:%s' # STRING,APP 设置信息,platform、channel、version |
|
65 |
+APP_PATCH_INFO = 'app:patch:info:%s:%s:%s' # STRING,APP 补丁信息,platform、version、src |
|
66 |
+ |
|
67 |
+# BOX 相关 |
|
68 |
+BOX_PROGRAM_VERSION_INFO = 'box:program:version:info' # STRING,BOX 程序版本信息 |